Czy można skonfigurować program Visual Studio 2008 tak, aby automatycznie usuwał białe znaki na końcu każdego wiersza podczas zapisywania pliku? Wygląda na to, że nie ma wbudowanej opcji, więc czy są dostępne jakieś rozszerzenia, które to zrobią?
Czy można skonfigurować program Visual Studio 2008 tak, aby automatycznie usuwał białe znaki na końcu każdego wiersza podczas zapisywania pliku? Wygląda na to, że nie ma wbudowanej opcji, więc czy są dostępne jakieś rozszerzenia, które to zrobią?
Odpowiedzi:
CodeMaid to bardzo popularne rozszerzenie programu Visual Studio, które robi to automatycznie wraz z innymi przydatnymi porządkami.
Ustawiłem go tak, aby czyścił plik przy zapisywaniu, co moim zdaniem jest domyślne.
Znajdź / zamień za pomocą wyrażeń regularnych
W oknie dialogowym Znajdź i zamień rozwiń opcje Znajdź , zaznacz Użyj , wybierz Wyrażenia regularne
Znajdź co : „ :Zs#$
”
Zamień na : „”
kliknij Zamień wszystko
W innych edytorach ( zwykły parser wyrażeń regularnych) „ :Zs#$
” byłoby „ \s*$
”.
[^\S\r\n]+(?=\r?$)
[:Zs\t]#$
jest to przydatna adaptacja.
Aby zrobić to za Ciebie, możesz utworzyć makro, które będzie wykonywane po zapisaniu.
Dodaj następujące elementy do modułu EnvironmentEvents dla swoich makr.
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
Używam tego od jakiegoś czasu bez żadnych problemów. Nie stworzyłem makra, ale zmodyfikowałem je z tego w ace_guidelines.vsmacros, które można znaleźć za pomocą szybkiego wyszukiwania w Google.
Możesz to łatwo zrobić, wykonując te trzy czynności:
Ctrl+ A(zaznacz cały tekst)
Edycja -> Zaawansowane -> Usuń poziome odstępy
Edycja -> Zaawansowane -> Wybór formatu
Poczekaj kilka sekund i gotowe.
Jest w stanie Ctrl+ Z'na wypadek, gdyby coś poszło nie tak.
Biorąc elementy ze wszystkich udzielonych już odpowiedzi, oto kod, który otrzymałem. (Piszę głównie kod w C ++, ale w razie potrzeby łatwo jest sprawdzić różne rozszerzenia plików).
Dziękujemy wszystkim, którzy wnieśli swój wkład!
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
Możesz użyć makra opisanego w sekcji Usuwanie białych znaków i przepisywanie komentarzy za pomocą wyszukiwania wyrażeń regularnych
Niestety używam programu VWD 2010 Express, w którym makra nie są obsługiwane. Więc po prostu zrobić kopiuj / wklej do Notepad ++ górnym lewym menu Edit
> Blank Operations
> Trim Trailing Space
istnieją inne związane z nimi operacje dostępne. Następnie skopiuj / wklej z powrotem do programu Visual Studio.
Można również użyć NetBeans zamiast Notepad ++, który ma „Usuń końcowe spacje” w menu „Źródło”.
Jeśli nie jest to projekt jednoosobowy, nie rób tego. Porównywanie lokalnych plików z repozytorium kodu źródłowego musi być trywialne, a wyczyszczenie białych znaków zmieniłoby wiersze, których nie trzeba zmieniać. Absolutnie rozumiem; Uwielbiam, gdy moje białe znaki są jednolite - ale jest to coś, z czego powinieneś zrezygnować, aby uzyskać czystszą współpracę.
Myślę, że wersja Jeffa Muira mogłaby być trochę ulepszona, gdyby tylko przycinała pliki z kodem źródłowym (w moim przypadku C #, ale łatwo jest dodać więcej rozszerzeń). Dodałem również sprawdzenie, czy okno dokumentu jest widoczne, ponieważ niektóre sytuacje bez tego sprawdzenia pokazują dziwne błędy (na przykład pliki 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
Osobiście uwielbiam rozszerzenie Trailing Whitespace Visualizer Visual Studio, które jest obsługiwane przez Visual Studio 2012.
Myślę, że mam wersję tego makra, która nie zawiesza VS2010 podczas refaktoryzacji, a także nie zawiesza IDE podczas zapisywania plików nietekstowych. Spróbuj tego:
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
Używam ArtisticStyle (C ++), aby to zrobić, a także ponownie formatuję mój kod. Musiałem jednak dodać to jako narzędzie zewnętrzne i musisz je uruchomić samodzielnie, więc może ci się to nie spodobać.
Jednak uważam za doskonałe, że mogę sformatować kod w bardziej niestandardowy sposób (na przykład parametry funkcji wielowierszowej), ponieważ mogę zapłacić cenę ręcznego uruchomienia. Narzędzie jest bezpłatne.
Opierając się na odpowiedzi Dyaus i wyrażeniu regularnym z raportu połączenia , oto makro, które obsługuje zapisz wszystko, nie zastępuje tabulatorów spacjami i nie wymaga zmiennej statycznej. Jego możliwy minus? Wydaje się trochę powolne, być może z powodu wielu wywołań 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
Dla każdego, kto próbuje użyć tego w dodatku Visual Studio 2012, wyrażenie regularne, którego użyłem, to [ \t]+(?=\r?$)
(nie zapomnij w razie potrzeby uciec przed ukośnikami odwrotnymi). Przyjechałem tu po kilku próbach daremnych naprawić problemy z surowego konwersji z {:b}+$
braku odpowiednio do powrotu karetki.
To jest naprawdę dobry przykład, jak usunąć końcowe białe spacje. Jest kilka rzeczy, które chciałbym zmienić w oparciu o to, co odkryłem za pomocą tego makra. Przede wszystkim makro automatycznie konwertuje tabulatory na spacje. Nie zawsze jest to pożądane i może prowadzić do pogorszenia sytuacji dla osób kochających karty (zazwyczaj oparte na Linuksie). Problem z tabulatorami nie jest tak naprawdę tym samym, co problem z dodatkowymi białymi znakami. Po drugie, makro zakłada, że zapisywany jest tylko jeden plik naraz. Jeśli zapiszesz wiele plików na raz, nie usunie to prawidłowo białych znaków. Powód jest prosty. Bieżący dokument jest uważany za dokument, który możesz zobaczyć. Po trzecie, nie sprawdza błędów w wynikach wyszukiwania. Te wyniki mogą dać lepsze informacje o tym, co robić dalej. Na przykład, jeśli nie zostanie znaleziona i zastąpiona żadna spacja, nie ma potrzeby ponownego zapisywania pliku. Ogólnie rzecz biorąc, nie podobało mi się, że flaga globalna jest zapisywana lub nie. Zwykle prosi o kłopoty w oparciu o nieznane stany. Podejrzewam, że flaga została dodana wyłącznie po to, aby zapobiec nieskończonej pętli.
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
Dodałem okna komunikatów debugowania, aby pomóc zobaczyć, co się dzieje. To bardzo wyraźnie pokazało, że zapis wielu plików nie działa. Jeśli chcesz się nimi bawić, odkomentuj te linie.
Kluczową różnicą jest użycie document.Activate () do wymuszenia przeniesienia dokumentu do aktywnego bieżącego dokumentu na pierwszy plan. Jeśli wynikiem jest 4, oznacza to, że tekst został zastąpiony. Zero oznacza, że nic się nie stało. Zobaczysz dwa zapisy dla każdego pliku. Pierwsza zastąpi, a druga nic nie zrobi. Potencjalnie mogą wystąpić problemy, jeśli funkcja save nie może zapisać pliku, ale miejmy nadzieję, że to zdarzenie nie zostanie wywołane, jeśli tak się stanie.
Przed powstaniem oryginalnego skryptu nie wiedziałem, jak działa skrypt w Visual Studio. Jest nieco zaskakujące, że używa Visual Basic jako głównego interfejsu, ale działa dobrze do tego, co musi zrobić.
Prostym dodatkiem jest usunięcie powrotu karetki podczas zapisywania.
' Remove all the carriage returns.
result = DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, _
"\x000d\x000a", _
vsFindOptions.vsFindOptionsRegularExpression, _
"\x000a", _
vsFindTarget.vsFindTargetCurrentDocument, , , _
vsFindResultsLocation.vsFindResultsNone)
Kluczem do tego działania jest zmiana \ x000d \ x000a na \ x000a. Przedrostek \ x wskazuje wzorzec Unicode. Zautomatyzuje to proces przygotowywania plików źródłowych dla systemów Linux.