Come rimuovere automaticamente gli spazi vuoti finali in Visual Studio 2008?


122

È possibile configurare Visual Studio 2008 per rimuovere automaticamente i caratteri di spazio alla fine di ogni riga quando si salva un file? Non sembra esserci un'opzione integrata, quindi ci sono estensioni disponibili per farlo?


1
Nota per coloro che leggono questo e utilizzano Visual Studio 2010: se installi l'estensione PowerCommands da Microsoft, puoi avere il documento formattato automaticamente quando salvi il file (attiva questa funzione tramite Strumenti / Opzioni). Ciò, tra le altre cose, rimuoverà lo spazio bianco finale non necessario.
steinar

Risposte:


68

CodeMaid è un'estensione di Visual Studio molto popolare e lo fa automaticamente insieme ad altre utili pulizie.

L'ho impostato per ripulire un file al salvataggio, che credo sia l'impostazione predefinita.


1
Questa è la migliore soluzione in questa pagina. È facilmente configurabile, fatto automaticamente per te su richiesta o su salvataggio, si integra bene con VS, ha molte altre funzionalità molto utili. Buon trovare arserbin3.
Chris R

Non è possibile disattivare la formattazione completa del codice in questa estensione, quindi non è compatibile, ad esempio, con gli stili di rientro personalizzati.
aemxdp

@Andriy non capisco cosa intendi. Segue qualsiasi rientro personalizzato impostato in Visual Studio. Impostali in Strumenti> Opzioni> Editor di testo> [Lingua]> Schede
arserbin3

@ arserbin3 Voglio dire, che se vuoi formattare il tuo codice in questo modo - pastebin.com/uJqBQ1u2 - sei sfortunato, perché al salvataggio riformatterà automaticamente il codice come pastebin.com/761Lzra7 o qualcosa del genere, a seconda opzioni. E non è possibile disattivare completamente le regole di rientro. E senza codemaid la riformattazione del file non viene eseguita automaticamente, quindi puoi salvare il tuo file con quel tipo di rientro.
aemxdp

6
@ arserbin3 Penso che ti stia perdendo il punto di Andriy. Sto lavorando a un enorme progetto open source. Non possiedo il codice, sto contribuendo al codice. Non posso modificare le linee guida di indentazione del progetto. Voglio che VisualStudio rimuova gli spazi vuoti finali quando modifico un file e non so cosa rovinare con qualsiasi altra cosa nel file (tabulazioni, spazi, rientri, ecc.). Finora, VisualStudio è l'unico IDE con cui ho lavorato che non può farlo. Qualsiasi altro editor a metà (per non parlare dell'IDE) può farlo. Non riesco a configurare CodeMaid su una certa formattazione, perché la formattazione varia.
kliteyn

71

Trova / Sostituisci utilizzando espressioni regolari

Nella finestra di dialogo Trova e sostituisci, espandere Trova Opzioni , selezionare Usa , scegliere le espressioni regolari

Trova cosa : " :Zs#$"

Sostituisci con : ""

fare clic su Sostituisci tutto

In altri editor (un normale parser di espressioni regolari) " :Zs#$" sarebbe " \s*$".


44
In VS2012 userei:[^\S\r\n]+(?=\r?$)
M. Dudley

4
Se usi le schede, [:Zs\t]#$è un utile adattamento.
dlanod

Come associarlo all'evento File su salvataggio in modo che venga eseguito ogni volta che salvo un file, per favore?
David Ferenczy Rogožan

30

Puoi creare una macro che viene eseguita dopo un salvataggio per farlo per te.

Aggiungi quanto segue nel modulo EnvironmentEvents per le tue macro.

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

Lo sto usando da un po 'di tempo senza problemi. Non ho creato la macro, ma l'ho modificata da quella in ace_guidelines.vsmacros che può essere trovata con una rapida ricerca su Google.


8
Nota che questo sostituisce anche le tabulazioni con due spazi.
crdx

Dove metti questi script di eventi del documento?
xagyg

Non sarebbe meglio farlo prima di un salvataggio, in modo da non ricevere quel fastidioso prompt di VS che dice "Ehi, il testo è cambiato dall'ultimo salvataggio. Vuoi ricaricare?"
jedmao

2
Purtroppo non ci sono più macro in VS 2013.
Nathan Baulch

17

Prima di salvare potresti essere in grado di utilizzare la scorciatoia di formattazione automatica CTRL+ K+ D.


11

Puoi farlo facilmente con queste tre azioni:

  • Ctrl+ A(seleziona tutto il testo)

  • Modifica -> Avanzate -> Elimina spazio bianco orizzontale

  • Modifica -> Avanzate -> Selezione formato

Aspetta qualche secondo e il gioco è fatto.

È Ctrl+ Zpossibile nel caso qualcosa sia andato storto.


1
C'è una scorciatoia per farlo: ctrl + w, a quindi digitare Edit.RemoveHorizontalWhitespace
Josh

8

Prendendo elementi da tutte le risposte già fornite, ecco il codice con cui sono finito. (Scrivo principalmente codice C ++, ma è facile controllare le diverse estensioni di file, se necessario.)

Grazie a tutti quelli che hanno contribuito!

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

Sto usando VWD 2010 Express dove le macro non sono supportate, sfortunatamente. Così ho solo fare copia / incolla in Notepad ++ menu in alto a sinistra Edit> Blank Operations> Trim Trailing Spaceci sono altre operazioni connesse a disposizione troppo. Quindi copia / incolla di nuovo in Visual Studio.

Si può anche usare NetBeans invece di Notepad ++, che ha "Rimuovi spazi finali" nel menu "Origine".


Basta trovare / sostituire: b + $ con una stringa vuota e puoi farlo nelle edizioni espresse di VS.
legalizza l'

1

A meno che questo non sia un progetto di una sola persona, non farlo. Deve essere banale diffondere i file locali con il repository del codice sorgente e la cancellazione degli spazi vuoti cambierebbe le righe che non è necessario modificare. Capisco bene; Mi piace avere i miei spazi bianchi tutti uniformi, ma questo è qualcosa a cui dovresti rinunciare per motivi di collaborazione più pulita.


17
La maggior parte dei buoni strumenti di differenza ignorano differenze non importanti come lo spazio bianco finale. Se il tuo strumento non ottiene Beyond Compare da scootersoftware.com
Jim McKeeth,

19
Se tutti in azienda / progetto lo fanno, i diff saranno puliti. Dovrai solo pulire tutti gli spazi bianchi una volta. Quindi hai un unico commit che risolve solo gli spazi bianchi e nessun problema di spazi bianchi in futuro.
ThiefMaster,

È vero. Ma se questo vola dipenderà dalla squadra. Aggiungere un passaggio in più al lavoro di tutti, o anche un'impostazione in più per mantenerli sincronizzati, tende a creare attriti inutili. Se il team può cambiare, o se i membri del team possono scegliere il proprio IDE, ecc., Allora ti suggerisco di lasciare che sia lo spazio bianco. Non è un grosso problema.
Kevin Conner,

3
Il problema con la pulizia degli spazi bianchi e dei rientri è che riduce l'efficacia delle funzionalità di controllo del codice sorgente come l'annotazione, e questo è un problema che Beyond Compare non risolverà. Meglio farlo bene la prima volta.
jammycakes

4
@KevinConner Sembra molto più difficile IMO mantenere coerenti gli spazi vuoti sbagliati piuttosto che risolverli una volta con un commit di spazi bianchi giganti all'inizio del progetto. Quindi, chiunque il cui editor sia stupido e rotto lo saprà quando controllerà i propri diff prima di eseguire il commit.
Dan Bechard

1

Penso che la versione di Jeff Muir potrebbe essere leggermente migliorata se ritagli solo i file del codice sorgente (nel mio caso C #, ma è facile aggiungere più estensioni). Inoltre ho aggiunto un controllo per assicurarmi che la finestra del documento sia visibile perché alcune situazioni senza quel controllo mi mostrano strani errori (ad esempio i file 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

Penso di avere una versione di questa macro che non bloccherà VS2010 durante il refactor e inoltre non bloccherà l'IDE durante il salvataggio di file non di testo. Prova questo:

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

Uso ArtisticStyle (C ++) per fare questo e riformattare anche il mio codice. Tuttavia, ho dovuto aggiungerlo come strumento esterno e devi attivarlo tu stesso, quindi potrebbe non piacerti.

Tuttavia, trovo eccellente poter riformattare il codice in un modo più personalizzato (ad esempio, parametri di funzione multilinea) che posso pagare il prezzo di eseguirlo manualmente. Lo strumento è gratuito.


0

Basandosi sulla risposta di Dyaus e su un'espressione regolare da un rapporto di connessione , ecco una macro che gestisce Salva tutto, non sostituisce le tabulazioni con spazi e non richiede una variabile statica. Il suo possibile svantaggio? Sembra un po 'lento, forse a causa di più chiamate 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

Per chiunque altro cerchi di usarlo in un componente aggiuntivo di Visual Studio 2012, l'espressione regolare che ho finito per usare è [ \t]+(?=\r?$)(non dimenticare di sfuggire alle barre rovesciate se necessario). Sono arrivato qui dopo diversi inutili tentativi di risolvere i problemi con una conversione grezza di {:b}+$non riuscire ad abbinare il ritorno a capo.


-1

Questo è un ottimo esempio di come rimuovere gli spazi vuoti finali. Ci sono alcune cose che cambierei in base a ciò che ho scoperto usando questa macro. Prima di tutto, la macro converte automaticamente le tabulazioni in spazi. Questo non è sempre desiderabile e potrebbe portare a peggiorare le cose per le persone che amano le schede (tipicamente basate su Linux). Il problema delle tabulazioni non è comunque lo stesso del problema degli spazi bianchi extra. In secondo luogo, la macro presuppone che venga salvato un solo file alla volta. Se salvi più file contemporaneamente, non rimuoverà correttamente lo spazio vuoto. Il motivo è semplice. Il documento corrente è considerato il documento che puoi vedere. Terzo, non esegue il controllo degli errori sui risultati della ricerca. Questi risultati possono fornire una migliore intelligenza su cosa fare dopo. Ad esempio, se non vengono trovati e sostituiti spazi vuoti, non è necessario salvare nuovamente il file. In generale, non mi piaceva la necessità della bandiera globale per essere salvata o meno. Tende a chiedere problemi in base a stati sconosciuti. Sospetto che la bandiera sia stata aggiunta esclusivamente per evitare un ciclo infinito.

    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

Ho aggiunto finestre di messaggio di debug per vedere cosa stava succedendo. È stato molto chiaro che il salvataggio di più file non funzionava. Se vuoi giocare con loro, rimuovi il commento da quelle battute.

La differenza fondamentale è l'utilizzo di document.Activate () per forzare il documento nel documento attivo attivo in primo piano. Se il risultato è 4, significa che il testo è stato sostituito. Zero significa che non è successo niente. Vedrai due salvataggi per ogni file. Il primo sostituirà e il secondo non farà nulla. Potenzialmente potrebbero esserci problemi se il salvataggio non è in grado di scrivere il file, ma si spera che questo evento non venga chiamato se ciò accade.

Prima dello script originale, non ero a conoscenza di come funzionava lo scripting in Visual Studio. È leggermente sorprendente che utilizzi Visual Basic come interfaccia principale, ma funziona perfettamente per quello che deve fare.


Una modifica a questo consiste nel supportare il salvataggio e il ripristino dello stato attivo sulla finestra che aveva lo stato attivo quando è iniziato il salvataggio. Basta salvare il documento attivo dopo il Try (utilizzando currdoc = DTE.ActiveDocument) e prima del document.Activate (). Dopo aver completato il salvataggio, rendi attivo il documento originale (currdoc.Activate ()). Sembra un po 'strano quando il focus viene cambiato durante il salvataggio, ma è meglio che perdere il focus sul codice che non stavi guardando.
Jeff Muir

-1

Una semplice aggiunta è rimuovere i ritorni a capo durante il salvataggio.

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

La chiave per questo funzionamento è cambiare \ x000d \ x000a in \ x000a. Il prefisso \ x indica un modello Unicode. Ciò automatizzerà il processo di preparazione dei file sorgente per i sistemi Linux.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.