Como remover automaticamente o espaço em branco à direita no Visual Studio 2008?

122

É possível configurar o Visual Studio 2008 para remover automaticamente caracteres de espaço em branco no final de cada linha ao salvar um arquivo? Parece não haver uma opção interna. Existem extensões disponíveis para isso?

ChrisN
fonte
1
Observe para aqueles que estão lendo isso usando o Visual Studio 2010: Se você instalar a extensão PowerCommands da Microsoft, poderá formatar o documento automaticamente ao salvar o arquivo (ative esse recurso em Ferramentas / Opções). Isso removerá, entre outras coisas, espaços em branco desnecessários.
steinar

Respostas:

68

O CodeMaid é uma extensão do Visual Studio muito popular e faz isso automaticamente junto com outras limpezas úteis.

Eu o configurei para limpar um arquivo ao salvar, que acredito ser o padrão.

arserbin3
fonte
1
Esta é a melhor solução nesta página. É facilmente configurável, feito automaticamente para você sob demanda ou salvamento, integra-se perfeitamente ao VS, possui muitos outros recursos muito úteis. Bom encontrar arserbin3.
Chris R
Não há como desativar a formatação de código completo nesta extensão, por isso é incompatível com, por exemplo, estilos de indentação personalizados.
aemxdp 28/09
@ Andy, eu não entendo o que você quer dizer. Segue qualquer indentação personalizada que você definir no visual studio. Defina-os em Ferramentas> Opções> Editor de texto> [Idioma]> Guias
arserbin3
@ arserbin3 Quero dizer, se você quiser formatar seu código assim - pastebin.com/uJqBQ1u2 - não terá sorte, pois ao salvar, ele reformatará automaticamente o código como pastebin.com/761Lzra7 ou algo assim, dependendo de opções E não há opção para desativar completamente as regras de recuo. E sem a reformatação de arquivo codemaid não é executada automaticamente, então você pode salvar seu arquivo com esse tipo de recuo.
aemxdp
6
@ arserbin3 Acho que você está perdendo o argumento de Andriy. Estou trabalhando em um grande projeto de código aberto. Não possuo o código - estou contribuindo para o código. Não posso alterar as diretrizes de indentação do projeto. Quero que o VisualStudio remova os espaços em branco finais quando modifico algum arquivo e não mexo com nada no arquivo (guias, espaços, recuo, etc.). Até agora, o VisualStudio é o único IDE com o qual trabalhei que não pode fazê-lo. Qualquer outro editor incompleto (sem falar no IDE) pode fazê-lo. Não consigo configurar o CodeMaid para alguma formatação, porque a formatação varia.
kliteyn
71

Localizar / substituir usando expressões regulares

Na caixa de diálogo Localizar e substituir, expanda Opções de localização , marque Usar , escolha Expressões regulares

Encontre o que : " :Zs#$"

Substitua por : ""

clique em Substituir tudo

Em outros editores (um analisador de Expressão Regular normal ) " :Zs#$" seria " \s*$".

Greg Ogle
fonte
44
No VS2012 eu usaria:[^\S\r\n]+(?=\r?$)
M. Dudley
4
Se você usar guias, [:Zs\t]#$é uma adaptação útil.
Dlanod 5/05
Como vinculá-lo ao evento File On Save, para que seja executado toda vez que eu salvar um arquivo, por favor?
David Ferenczy Rogožan
30

Você pode criar uma macro que é executada após um salvamento para fazer isso por você.

Adicione o seguinte ao módulo EnvironmentEvents para suas macros.

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

Estou usando isso há algum tempo agora sem problemas. Eu não criei a macro, mas a modifiquei de ace_guidelines.vsmacros, que pode ser encontrada com uma rápida pesquisa no Google.


fonte
8
Observe que isso também substitui as guias por dois espaços.
23411 crdx
Onde você coloca esses scripts de eventos do documento?
xagyg 27/02
Não seria melhor fazer isso antes de salvar, para que você não receba o prompt irritante do VS que diz: "Ei, o texto mudou desde a última salva. Deseja recarregar?"
jedmao
2
Infelizmente, não há mais macros no VS 2013.
precisa saber é o seguinte
17

Antes de salvar, você poderá usar o atalho de formatação automática CTRL+ K+ D.

Vyrotek
fonte
11

Você pode fazer isso facilmente com estas três ações:

  • Ctrl+ A(selecione todo o texto)

  • Editar -> Avançado -> Excluir espaço em branco horizontal

  • Editar -> Avançado -> Seleção de Formato

Aguarde alguns segundos e pronto.

É de Ctrl+ Z'poder em caso de algo errado.

iPixel
fonte
1
Há uma shorcut para fazer isso: ctrl + w, um digite Edit.RemoveHorizontalWhitespace
Josh
8

Tomando elementos de todas as respostas já dadas, aqui está o código que eu acabei. (Eu escrevo principalmente código C ++, mas é fácil verificar diferentes extensões de arquivo, conforme necessário.)

Obrigado a todos que contribuíram!

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
fonte
2

Estou usando o VWD 2010 Express, onde macros não são suportadas, infelizmente. Então, eu só fazer copy / paste para Notepad ++ menu esquerdo superior Edit> Blank Operations> Trim Trailing Spaceexistem outras operações disponíveis também. Em seguida, copie / cole novamente no Visual Studio.

Também é possível usar o NetBeans em vez do Notepad ++, que possui "Remover espaços finais" no menu "Origem".

Evgenii
fonte
Basta encontrar / substituir: b + $ por uma string vazia e você pode fazê-lo nas edições expressas do VS.
legalize
1

A menos que seja um projeto de uma pessoa, não faça isso. Deve ser trivial diferenciar seus arquivos locais do seu repositório de código-fonte, e limpar o espaço em branco alteraria as linhas que você não precisa alterar. Eu compreendo totalmente; Eu amo uniformizar meu espaço em branco - mas isso é algo que você deve desistir por uma colaboração mais limpa.

Kevin Conner
fonte
17
A maioria das boas ferramentas de diferenças ignora diferenças sem importância, como o espaço em branco à direita. Se sua ferramenta não em seguida, se Beyond Compare de scootersoftware.com
Jim McKeeth
19
Se todos na empresa / projeto fizerem isso, as diferenças estarão limpas. Você só precisará limpar todos os espaços em branco uma vez. Então você tem um único commit corrigindo apenas problemas de espaço em branco e sem espaços no futuro.
ThiefMaster
Isso é verdade. Mas se isso voa dependerá da equipe. Adicionar uma etapa extra ao trabalho de todos, ou mesmo uma configuração extra para manter a sincronização, tende a criar atritos desnecessários. Se a equipe puder mudar, ou se os membros da equipe puderem escolher seu próprio IDE etc., sugiro que você deixe o espaço em branco. Não é grande coisa.
21810 Kevin Conner
3
O problema com a limpeza de espaço em branco e recuo é que ele reduz a eficácia dos recursos de controle de origem, como anotação, e esse é um problema que o Beyond Compare não resolverá. Melhor acertar na primeira vez.
Jammycakes # 14/11
4
@KevinConner Parece muito mais difícil para a IMO manter consistentemente o espaço em branco errado do que corrigi-lo uma vez com uma confirmação de espaço em branco gigante no início do projeto. Então, qualquer pessoa cujo editor seja estúpido e quebrado o saberá quando verificarem suas diferenças antes de cometer.
193 em Dan Bechard
1

Eu acho que a versão de Jeff Muir poderia ser um pouco melhorada se apenas aparasse os arquivos de código-fonte (no meu caso, C #, mas é fácil adicionar mais extensões). Também adicionei uma verificação para garantir que a janela do documento esteja visível, porque algumas situações sem essa verificação me mostram erros estranhos (arquivos LINQ to SQL '* .dbml', por exemplo).

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
fonte
0

Acho que tenho uma versão dessa macro que não trava o VS2010 no refator e também não trava o IDE ao salvar arquivos que não são de texto. Tente o seguinte:

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
fonte
0

Eu uso ArtisticStyle (C ++) para fazer isso e também reformatar meu código. No entanto, eu tive que adicionar isso como uma ferramenta externa e você precisa ativá-lo para não gostar.

No entanto, acho excelente poder reformatar o código de maneira mais personalizada (por exemplo, parâmetros de função de várias linhas) e pagar o preço de executá-lo manualmente. A ferramenta é gratuita.

Marcin Gil
fonte
0

Com base na resposta de Dyaus e em uma expressão regular de um relatório de conexão , aqui está uma macro que trata de salvar tudo, não substitui as guias por espaços e não requer uma variável estática. Sua possível desvantagem? Parece um pouco lento, talvez devido a várias chamadas para 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

Para qualquer outra pessoa que tente usar isso em um suplemento do Visual Studio 2012, a expressão regular que acabei usando é [ \t]+(?=\r?$)(não se esqueça de escapar das barras invertidas, se necessário). Cheguei aqui após várias tentativas inúteis de corrigir os problemas com uma conversão bruta de {:b}+$falha na correspondência com o retorno de carro.

Michael Urman
fonte
-1

Este é realmente um bom exemplo de como remover o espaço em branco à direita. Há algumas coisas que eu mudaria com base no que descobri usando essa macro. Primeiro de tudo, a macro converte guias automaticamente em espaços. Isso nem sempre é desejável e pode levar a piorar as coisas para as pessoas que amam guias (geralmente baseadas em Linux). O problema da guia não é realmente o mesmo que o problema de espaço em branco extra. Em segundo lugar, a macro assume que apenas um arquivo está sendo salvo de uma vez. Se você salvar vários arquivos de uma vez, ele não removerá corretamente o espaço em branco. O motivo é simples. O documento atual é considerado o documento que você pode ver. Terceiro, não há erro ao verificar os resultados encontrados. Esses resultados podem fornecer uma melhor inteligência sobre o que fazer em seguida. Por exemplo, se nenhum espaço em branco for encontrado e substituído, não há necessidade de salvar o arquivo novamente. Em geral, eu não gostei da necessidade de a bandeira global ser salva ou não. Tende a pedir problemas com base em estados desconhecidos. Eu suspeito que o sinalizador tenha sido adicionado apenas para impedir um loop 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

Adicionei caixas de mensagem de depuração para ajudar a ver o que estava acontecendo. Deixou bem claro que o salvamento de vários arquivos não estava funcionando. Se você quiser brincar com eles, remova o comentário dessas linhas.

A principal diferença é usar document.Activate () para forçar o documento para o documento atual ativo em primeiro plano. Se o resultado for 4, isso significa que o texto foi substituído. Zero significa que nada aconteceu. Você verá duas gravações para cada arquivo. O primeiro substituirá e o segundo não fará nada. Possivelmente, poderá haver problemas se o salvamento não puder gravar o arquivo, mas espero que este evento não seja chamado se isso acontecer.

Antes do script original, eu não sabia como os scripts funcionavam no Visual Studio. É um pouco surpreendente que ele use o Visual Basic como interface principal, mas funcione bem para o que precisa fazer.

Jeff Muir
fonte
Uma mudança é apoiar o salvamento e a restauração do foco na janela que tinha o foco quando o salvamento foi iniciado. Apenas salve o documento ativo após o Try (usando currdoc = DTE.ActiveDocument) e antes do document.Activate (). Após a conclusão do salvamento, basta ativar o documento original (currdoc.Activate ()). Parece um pouco engraçado quando o foco é alterado durante o salvamento, mas é melhor do que perder o foco no código que você não estava olhando.
Jeff Muir
-1

Uma adição simples é remover retornos de carro durante o salvamento.

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

A chave para este trabalho está mudando \ x000d \ x000a para \ x000a. O prefixo \ x indica um padrão Unicode. Isso automatizará o processo de preparação dos arquivos de origem para os sistemas Linux.

Jeff Muir
fonte