Is there a way to enforce using tabs instead of spaces?

前端 未结 7 1698

StyleCop offers to check for consistent use of spaces, but sadly lacks the opposite idea: Force source code to use tabs. Is there some way to add this functionality? It does

相关标签:
7条回答
  • 2021-01-01 18:23

    I'm a tabs-not-spaces person, too, though there are plenty of reasons to use either one and there are other places to get into why you think one is better than the other. :)

    I actually wanted the same thing - a rule to check for tab indents - so I wrote it based on the SpacingRules source from StyleCop. It seems to work reasonably well, though I've only used it on a few projects so far. It could probably be optimized or whatever... but it works.

    using System;
    using System.Text.RegularExpressions;
    using Microsoft.StyleCop;
    using Microsoft.StyleCop.CSharp;
    
    namespace CustomRules.StyleCop.CSharp
    {
      [SourceAnalyzer(typeof(CsParser))]
      public class SpacingRules : SourceAnalyzer
      {
        public SpacingRules()
        {
        }
    
        public override void AnalyzeDocument(CodeDocument document)
        {
          Param.RequireNotNull(document, "document");
    
          CsDocument csdocument = (CsDocument)document;
          if (csdocument.RootElement != null && !csdocument.RootElement.Generated)
          {
            this.CheckSpacing(csdocument.Tokens);
          }
        }
    
        private void CheckSpacing(MasterList<CsToken> tokens)
        {
          Param.AssertNotNull(tokens, "tokens");
    
          foreach (var token in tokens)
          {
            if (this.Cancel)
            {
              break;
            }
    
            if (token.Generated)
            {
              continue;
            }
    
            switch (token.CsTokenType)
            {
              case CsTokenType.WhiteSpace:
                this.CheckWhitespace(token as Whitespace);
                break;
    
              case CsTokenType.XmlHeader:
                XmlHeader header = (XmlHeader)token;
                foreach (var xmlChild in header.ChildTokens)
                {
                  this.CheckTabsInComment(xmlChild);
                }
                break;
    
              case CsTokenType.SingleLineComment:
              case CsTokenType.MultiLineComment:
                this.CheckTabsInComment(token);
                break;
            }
    
            switch (token.CsTokenClass)
            {
              case CsTokenClass.ConstructorConstraint:
                this.CheckSpacing(((ConstructorConstraint)token).ChildTokens);
                break;
    
              case CsTokenClass.GenericType:
                this.CheckGenericSpacing((GenericType)token);
                this.CheckSpacing(((TypeToken)token).ChildTokens);
                break;
    
              case CsTokenClass.Type:
                this.CheckSpacing(((TypeToken)token).ChildTokens);
                break;
            }
          }
        }
    
        private void CheckGenericSpacing(GenericType generic)
        {
          Param.AssertNotNull(generic, "generic");
          if (generic.ChildTokens.Count == 0)
          {
            return;
          }
    
          foreach (var token in generic.ChildTokens)
          {
            if (this.Cancel)
            {
              break;
            }
    
            if (token.CsTokenClass == CsTokenClass.GenericType)
            {
              this.CheckGenericSpacing(token as GenericType);
            }
    
            if (!token.Generated && token.CsTokenType == CsTokenType.WhiteSpace)
            {
              this.CheckWhitespace(token as Whitespace);
            }
          }
        }
    
        private void CheckWhitespace(Whitespace whitespace)
        {
          Param.AssertNotNull(whitespace, "whitespace");
    
          if (whitespace.Location.StartPoint.IndexOnLine == 0 && Regex.IsMatch(whitespace.Text, "^ +"))
          {
            this.AddViolation(whitespace.FindParentElement(), whitespace.LineNumber, "TabsMustBeUsed");
          }
        }
    
        private void CheckTabsInComment(CsToken comment)
        {
          Param.AssertNotNull(comment, "comment");
    
          var lines = comment.Text.Split('\n');
          for (int i = 0; i < lines.Length; i++)
          {
            if (Regex.IsMatch(lines[i], "^ +"))
            {
              this.AddViolation(comment.FindParentElement(), comment.LineNumber + i, "TabsMustBeUsed");
            }
          }
        }
      }
    }
    

    Note that you also have to have the embedded XML file "SpacingRules.xml" in the assembly alongside this thing. (Read the StyleCop SDK doc for more on that.)

    <?xml version="1.0" encoding="utf-8" ?>
    <SourceAnalyzer Name="Custom Spacing Rules">
      <Description>
        Rules which verify the spacing placed between keywords and symbols in the code.
      </Description>
      <Rules>
        <Rule Name="TabsMustBeUsed" CheckId="MY1027">
          <Context>Spaces are not allowed. Use tabs instead.</Context>
          <Description>Verifies that the code does not contain spaces.</Description>
        </Rule>
      </Rules>
    </SourceAnalyzer>
    
    0 讨论(0)
  • 2021-01-01 18:25

    You can use StyleCop+ plugin to enforce usage of tabs.

    After downloading StyleCopPlus.dll place it in Custom Rules folder inside the main StyleCop folder C:\Program Files (x86)\StyleCop 4.7\Custom Rules or directly in the main folder.

    Now, when opening a Settings.StyleCop with StyleCopSettingsEditor you will be able to set rule SP2001: CheckAllowedIndentationCharacters.

    This rule can be found under the StyleCop+ tab, under the More Custom Rules subtab, under the Formatting heading:

    Rule Options

    0 讨论(0)
  • 2021-01-01 18:25

    Ok I managed to figure out the problem because the reason why this warning appear, It appear because the developer sometimes copy and paste the code

    if you are using VS2010 Go to solution explorer Check in Setting Style Cop then modify the setting inside the style Cop e.g disable or uncheck the setting[Spacing.....]

    0 讨论(0)
  • 2021-01-01 18:26

    One thing you could do, assuming you are using Visual Studio as your IDE, and that your team-mates buy-in to this idea, would be to set VS to use tabs instead of spaces, export and share the settings file.

    The setting can be found under Tools > Options > Text Editor > All Languages (or the language you wish to use) > Tabs and then on the right hand side you can pick to 'Insert Spaces' or 'Keep Tabs'.

    To export the settings from your visual studio: Tools > Import and Export Settings > Export selected environment settings > select the 'Options'

    Just a thought - but to be honest the real problem seems to be the buy-in from your team-mates. They can always revert back to their settings otherwise. Alternatively, upon check-in, as Sam suggested, you can do some automated re-formatting.

    HTH

    0 讨论(0)
  • 2021-01-01 18:29

    Do it within your source control server. Use a pre-commit script to check the file for lines starting with multiple spaces and prevent the commit.

    I agree tabs are better than spaces. It's a personal preference, but team consistency is very important.

    0 讨论(0)
  • 2021-01-01 18:31

    StyleCop supports creation of custom rules, so you can add your own "use leading tabs instead of spaces" rule. If you don't feel like trying to develop your own, you can get an existing rule at either http://stylecopcontrib.codeplex.com/ or http://github.com/AArnott/nerdbank.stylecop.rules.

    0 讨论(0)
提交回复
热议问题