2008-09-17 14 views
116

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

+1

nota a coloro che leggono questo che utilizzano Visual Studio 2010: se si installa l'estensione PowerCommands da Microsoft, è può avere il documento formattato automaticamente quando si salva il file (attivare questa funzione tramite Strumenti/Opzioni). Questo, tra le altre cose, rimuoverà lo spazio bianco finale non necessario. – steinar

risposta

62

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

ho impostato per ripulire un file al momento del salvataggio, che credo sia il default.

+1

Questa è la soluzione migliore su questa pagina. È facilmente configurabile, è fatto automaticamente per te su richiesta o su salvataggio, si integra bene con VS, ha molte altre funzioni molto utili. Buona ricerca arserbin3. –

+0

Non esiste alcun modo per disattivare la formattazione completa del codice in questa estensione, quindi non è compatibile con, ad esempio, gli stili di indentazione personalizzati. – aemxdp

+0

@Andriy Non capisco cosa intendi. Segue qualsiasi indentazione personalizzata impostata in Visual Studio. Impostali in Strumenti> Opzioni> Editor di testo> [Lingua]> Schede – arserbin3

0

Io uso ArtisticStyle (C++) per fare questo e anche riformattare il mio codice. Tuttavia, ho dovuto aggiungere questo come strumento esterno e devi attivarlo da solo in modo che non ti piaccia.

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

66

Trova/sostituzione con espressioni regolari

Nella finestra di dialogo Trova e sostituisci, espandere trovare delle opzioni, controllare Usa, scegliere espressioni regolari

trovare ciò: ":Zs#$"

Sostituire con: ""

click Sostituisci tutto

In altri editor (un normale espressione regolare parser) ":Zs#$" sarebbe "\s*$".

+38

In VS2012 vorrei usare: '[^ \ S \ r \ n] + (? = \ R? $)' –

+2

Questa è la risposta più semplice e veloce sulla pagina, non tutti vogliono che le estensioni rallentino il loro VS –

+19

domanda dice "automaticamente quando si salva" – danio

16

prima del salvataggio si può essere in grado di utilizzare la scorciatoia auto-formato CTRL +K +D.

+5

dai, qualsiasi altra opzione descritta qui è ridicolo. – fijiaaron

+1

Sembra solo rimuovere gli spazi bianchi dalle linee vuote. – danio

+0

Questo collegamento non è disponibile per C++. Ho provato in VS2010 –

1

A meno che non si tratti di un progetto di una sola persona, non farlo. Deve essere banale diffare i tuoi file locali contro il tuo repository del codice sorgente, e cancellare spazi bianchi cambierebbe le linee che non hai bisogno di cambiare. Capisco bene; Mi piace rendere il mio spazio bianco uniforme - ma è qualcosa che dovresti rinunciare per una collaborazione più pulita.

+16

Gli strumenti di differenziazione più validi ignorano le differenze non importanti come lo spazio bianco finale. Se il tuo strumento non ottiene Beyond Compare da http://www.scootersoftware.com/ –

+18

Se tutti nella società/progetto lo fanno, diffs sarà pulito. Dovrai solo pulire tutti gli spazi una volta. Quindi hai un singolo commit che risolve solo gli spazi bianchi e nessun problema con gli spazi bianchi in futuro. – ThiefMaster

+0

È vero. Ma se le mosche dipenderanno dalla squadra. Aggiungendo un passaggio in più al lavoro di tutti, o anche un'impostazione extra da tenere sincronizzati, tende a creare inutili attriti. Se la squadra può cambiare, o se i membri del team devono scegliere il proprio IDE, ecc. Allora ti suggerisco di lasciare che sia lo spazio bianco. Non è un grosso problema. –

31

È possibile creare una macro che viene eseguita dopo un salvataggio per farlo.

Aggiungere quanto segue al modulo EnvironmentEvents per i propri 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 uso 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.

+7

Nota che questo sostituisce anche le schede con due spazi. – crdx

+2

@ user457104 come le schede sono malvagie. :-) –

+0

Dove metti questi script di eventi del documento? – xagyg

-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 schede in spazi. Questo non è sempre auspicabile e potrebbe portare a peggiorare le cose per le persone che amano le schede (tipicamente basate su Linux). Il problema della tabulazione non è in realtà lo stesso del problema dello spazio bianco 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 bianco. La ragione è semplice. Il documento corrente è considerato il documento che puoi vedere. In terzo luogo, non esegue il controllo degli errori sui risultati di ricerca. Questi risultati possono dare una migliore intelligenza su cosa fare dopo. Ad esempio, se non vengono trovati e sostituiti spazi bianchi, non è necessario salvare di nuovo il file. In generale, non mi piaceva la necessità che la bandiera globale venisse salvata o meno. Tende a chiedere guai basati su stati sconosciuti. Sospetto che la bandiera sia stata aggiunta esclusivamente per impedire 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 caselle di messaggi di debug per vedere cosa stava succedendo. Ha reso molto chiaro che il salvataggio di più file non funzionava. Se vuoi giocare con loro, decommenta quelle linee.

La differenza fondamentale è l'utilizzo di document.Activate() per forzare il documento nel documento corrente attivo in primo piano. Se il risultato è 4, significa che il testo è stato sostituito. Zero significa che non è successo nulla. Vedrai due salvataggi per ogni file. Il primo sostituirà e il secondo non farà nulla. Potenzialmente potrebbero esserci problemi se il salvataggio non può 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 funzionavano gli script in Visual Studio. È leggermente sorprendente che utilizzi Visual Basic come interfaccia principale, ma funziona perfettamente per quello che deve fare.

+0

Una modifica a ciò è per supportare il salvataggio e il ripristino dello stato attivo sulla finestra che aveva lo stato attivo all'avvio del salvataggio. Basta salvare il documento attivo dopo la Prova (utilizzando currdoc = DTE.ActiveDocument) e prima del documento.Attiva(). Al termine del salvataggio, è sufficiente rendere attivo il documento originale (currdoc.Activate()). Sembra un po 'strano quando la messa a fuoco viene spostata durante il salvataggio, ma è meglio che perdere il focus sul codice che non stavi guardando. –

1

Penso che la versione di Jeff Muir potrebbe essere leggermente migliorata se taglia solo i file di codice sorgente (nel mio caso C#, ma è facile aggiungere altre estensioni). Inoltre ho aggiunto un controllo per garantire che la finestra del documento sia visibile perché alcune situazioni senza quel controllo mi mostrano errori strani (LINQ a file SQL '* .dbml', per esempio).

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 
-1

Un'aggiunta semplice è 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 sta cambiando \ x000d \ x000a in \ x000a. Il prefisso x indica un modello Unicode. Questo automatizzerà il processo di acquisizione dei file sorgente pronti per i sistemi Linux.

0

Basandosi sulla risposta di Dyaus e un'espressione regolare da un connect report, ecco una macro che gestisce salva tutto, non sostituisce le schede 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 cercando di utilizzare questo in un Visual Studio 2012 componente aggiuntivo, l'espressione regolare Ho finito per usare è [ \t]+(?=\r?$) (non dimenticate di sfuggire alle backslash se necessario). Sono arrivato qui dopo diversi inutili tentativi di risolvere i problemi con un raw conversion di {:b}+$ in mancanza di corrispondenza con il ritorno a capo.

7

Prendendo gli elementi da tutte le risposte già date, ecco il codice con cui ho finito. (I principalmente scrivere il codice C++, ma è facile da controllare per le diverse estensioni di file, se necessario.)

Grazie a tutti coloro 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 
9

Lo si può fare facilmente con queste tre azioni:

  • Ctrl + A (selezionare tutto il testo)

  • Modifica -> Avanzate -> Elimina orizzontale spazio bianco

  • Modifica -> Avanzate -> Selezione formato

Attendere alcuni secondi e terminare.

E 'Ctrl +Z 'in grado in caso qualcosa è andato storto.

+1

C'è uno shorcut per fare questo: ctrl + w, a quindi digitare Edit.RemoveHorizontalWhitespace – Josh

+0

risposta impressionante. Semplice e veloce. –

+0

Questo purtroppo rimuoverà gli spazi all'interno di litterali di stringhe ... – Gathar

0

Penso di avere una versione di questa macro che non causerà il crash di VS2010 sul refactor, e inoltre non appenderà l'IDE quando si salvano 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 
2

Sto usando VWD 2010 Express in cui non sono supportate le macro, purtroppo. Quindi faccio solo copia/incolla nel menu Edit>Blank Operations>Trim Trailing SpaceNotepad++ in alto sono disponibili anche altre operazioni correlate. Quindi copia/incolla di nuovo in Visual Studio.

È inoltre possibile utilizzare NetBeans anziché Notepad ++, che contiene "Rimuovi spazi finali" nel menu "Origine".

+0

Trova/sostituisci: b + $ con stringa vuota e puoi farlo nelle edizioni Express di VS. – legalize