69 votes

Existe-t-il un moyen de faire en sorte que Visual Studio cesse d'indenter les espaces de noms ?

Visual Studio continue d'essayer d'indenter le code à l'intérieur des espaces de noms.

Par exemple :

namespace Foo
{
   void Bar();

   void Bar()
   {

   }

}

Maintenant, si je le désindente manuellement, il reste comme ça. Mais malheureusement, si j'ajoute quelque chose juste avant void Bar(); - comme un commentaire - VS va continuer à essayer de l'indenter.

C'est tellement ennuyeux qu'à cause de cette seule raison, je n'utilise presque jamais les espaces de noms en C++. Je ne comprends pas pourquoi il essaie de les indenter (quel est l'intérêt d'indenter 1 ou même 5 tabulations). l'ensemble du fichier ?), ou comment l'arrêter.

Existe-t-il un moyen de mettre fin à ce comportement ? Une option de configuration, un add-in, un paramètre de registre, voire même un hack qui modifie directement devenv.exe.

0 votes

Vous pourriez désactiver entièrement l'indentation automatique. Ou le paramétrer pour qu'il soit indenté d'une quantité moindre (par exemple, 2 espaces au lieu d'une tabulation).

3 votes

Ce problème (paramètres d'indentation non configurables) est l'une des nombreuses raisons pour lesquelles j'ai arrêté d'éditer des fichiers dans Visual Studio il y a des années... :)

2 votes

J'attribuerai la prime à celui qui trouvera une solution sans effets secondaires, ou avec le moins d'effets secondaires possible. Pour l'instant, la meilleure réponse, selon moi, est celle de Bacar ; si aucune meilleure réponse n'est fournie, je lui attribuerai la réponse.

31voto

bacar Points 2017

N'insérez rien avant la première ligne de code. Vous pouvez essayer l'approche suivante pour insérer une ligne de code nulle (cela semble fonctionner dans VS2005) :

namespace foo
{; // !<---
void Test();
}

Cela semble supprimer l'indentation, mais les compilateurs peuvent émettre des avertissements et les réviseurs/mainteneurs de code peuvent être surpris ! (Et à juste titre, dans le cas habituel !)

11 votes

J'aime bien ça aussi. Il semble que même une macro qui ne s'étend à rien soit suffisante pour supprimer l'indentation. Donc vous pouvez #define SUPPRESS_INDENTATION et ensuite ouvrir l'espace de nom comme namespace foo { SUPPRESS_INDENTATION :)

0 votes

Joli - l'intention est un peu plus claire et le compilateur est, espérons-le, moins susceptible d'émettre des avertissements :)

0 votes

Bien que cela ait été ma solution préférée, je voulais mentionner que cette astuce ne fonctionne pas dans VS2013. Il y a un paramètre de configuration utilisateur dans VS2013 qui empêche cela de se produire (quand cela fonctionne ; voir autre réponse).

14voto

Ken Simon Points 1034

Ce n'est probablement pas ce que vous vouliez entendre, mais beaucoup de gens contournent ce problème en utilisant des macros :

#define BEGIN\_NAMESPACE(x) namespace x {
#define END\_NAMESPACE }

Cela semble stupide, mais vous seriez surpris de voir combien d'en-têtes de système l'utilisent. (l'implémentation stl de la glibc, par exemple, a _GLIBCXX_BEGIN_NAMESPACE() pour cela.)

Je préfère en fait cette façon de faire, car j'ai toujours tendance à grimacer lorsque je vois des lignes non indentées suivre un fichier { . Mais ce n'est que moi.

9 votes

Je pense que c'est plus pour la compatibilité avec les anciens compilateurs qu'à cause de Visual Studio =)

6 votes

@andreas Je pense que de cette façon vous pouvez changer l'espace de nom de la librairie entière facilement sans éditer tous les fichiers sources.

13voto

Rod Points 7510

Voici une macro qui pourrait vous aider. Elle supprimera l'indentation si elle détecte que vous êtes en train de créer un fichier de type namespace . Il n'est pas parfait mais semble fonctionner jusqu'à présent.

Public Sub aftekeypress(ByVal key As String, ByVal sel As TextSelection, ByVal completion As Boolean) _
        Handles TextDocumentKeyPressEvents.AfterKeyPress
    If (Not completion And key = vbCr) Then
        'Only perform this if we are using smart indent
        If DTE.Properties("TextEditor", "C/C++").Item("IndentStyle").Value = 2 Then
            Dim textDocument As TextDocument = DTE.ActiveDocument.Object("TextDocument")
            Dim startPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
            Dim matchPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
            Dim findOptions As Integer = vsFindOptions.vsFindOptionsMatchCase + vsFindOptions.vsFindOptionsMatchWholeWord + vsFindOptions.vsFindOptionsBackwards
            If startPoint.FindPattern("namespace", findOptions, matchPoint) Then
                Dim lines = matchPoint.GetLines(matchPoint.Line, sel.ActivePoint.Line)
                ' Make sure we are still in the namespace {} but nothing has been typed
                If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace[\s\w]+)?[\s\{]+$") Then
                    sel.Unindent()
                End If
            End If
        End If
    End If
End Sub

Étant donné qu'elle fonctionne en permanence, vous devez vous assurer que vous installez la macro à l'intérieur de votre fichier EnvironmentEvents élément du projet dans MyMacros. Vous ne pouvez accéder à ce module que dans l'explorateur de macros (Outils->Macros->Explorateur de macros).

Il convient de noter qu'il ne prend pas actuellement en charge les espaces de noms "emballés" tels que

namespace A { namespace B {
...
}
}

EDIT

Pour prendre en charge les espaces de noms "emballés" tels que l'exemple ci-dessus et/ou prendre en charge les commentaires après l'espace de noms, tels que namespace A { /* Example */ vous pouvez essayer d'utiliser la ligne suivante à la place :

 If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace.+)?[\s\{]+$") Then

Je n'ai pas encore eu l'occasion de le tester à fond, mais il semble que cela fonctionne.

0 votes

Merci beaucoup pour votre réponse. Il y avait une erreur que j'ai maintenant corrigée, mais à part ça, ça fonctionne parfaitement. Félicitations pour la prime.

0 votes

Cela fonctionne bien pour la saisie, mais pas pour le collage ou, par exemple, la fonctionnalité "Créer une implémentation" de Visual Assist, alors que la solution de Bacar fait l'affaire. Elle est cependant plus propre.

1 votes

La question peut paraître stupide, mais je ne trouve vraiment pas de réponse : où doit-on coller cette macro ?

8voto

metator Points 149

Vous pouvez également déclarer vos types (ou autres) à l'intérieur de l'espace de noms et les implémenter à l'extérieur comme ceci :

namespace test {
    class MyClass;
}

class test::MyClass {
//...
};

3voto

Je comprends le problème lorsqu'il y a des espaces de noms imbriqués. J'avais l'habitude d'emballer tous les namespace dans une seule ligne pour éviter l'indentation multiple. Cela laissera un niveau, mais ce n'est pas aussi grave que plusieurs niveaux. Cela fait tellement longtemps que je n'ai pas utilisé VS que je me souviens à peine de cette époque.

namespace outer { namespace middle { namespace inner {
    void Test();
    .....
}}}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X