代码之家  ›  专栏  ›  技术社区  ›  mafu

有没有办法强制使用制表符而不是空格?

  •  18
  • mafu  · 技术社区  · 16 年前

    Stylecop提供检查空间的一致性使用,但遗憾的是,它缺少相反的想法:强制源代码使用制表符。有什么方法可以添加这个功能吗?它不必是样式警察,也欢迎使用其他工具。

    7 回复  |  直到 8 年前
        2
  •  12
  •   Travis Illig    15 年前

    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");
            }
          }
        }
      }
    }
    

    <?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>
    
        3
  •  3
  •   FOR    16 年前

        5
  •  2
  •   Brian Kagiso    14 年前

        6
  •  2
  •   James John McGuire 'Jahmic'    8 年前

    Install-Package Microsoft.CodeAnalysis.FxCopAnalyzers
    Install-Package StyleCop.Analyzers -Version 1.1.0-beta006
    

    <?xml version="1.0" encoding="utf-8"?>
    <RuleSet Name="Custom Rulset" Description="Custom Rulset" ToolsVersion="14.0">
        <Rules AnalyzerId="AsyncUsageAnalyzers" RuleNamespace="AsyncUsageAnalyzers">
            <Rule Id="UseConfigureAwait" Action="Warning" />
        </Rules>
        <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
            <Rule Id="CA1001" Action="Warning" />
            <Rule Id="CA1009" Action="Warning" />
            <Rule Id="CA1016" Action="Warning" />
            <Rule Id="CA1033" Action="Warning" />
            <Rule Id="CA1049" Action="Warning" />
            <Rule Id="CA1060" Action="Warning" />
            <Rule Id="CA1061" Action="Warning" />
            <Rule Id="CA1063" Action="Warning" />
            <Rule Id="CA1065" Action="Warning" />
            <Rule Id="CA1301" Action="Warning" />
            <Rule Id="CA1400" Action="Warning" />
            <Rule Id="CA1401" Action="Warning" />
            <Rule Id="CA1403" Action="Warning" />
            <Rule Id="CA1404" Action="Warning" />
            <Rule Id="CA1405" Action="Warning" />
            <Rule Id="CA1410" Action="Warning" />
            <Rule Id="CA1415" Action="Warning" />
            <Rule Id="CA1821" Action="Warning" />
            <Rule Id="CA1900" Action="Warning" />
            <Rule Id="CA1901" Action="Warning" />
            <Rule Id="CA2002" Action="Warning" />
            <Rule Id="CA2100" Action="Warning" />
            <Rule Id="CA2101" Action="Warning" />
            <Rule Id="CA2108" Action="Warning" />
            <Rule Id="CA2111" Action="Warning" />
            <Rule Id="CA2112" Action="Warning" />
            <Rule Id="CA2114" Action="Warning" />
            <Rule Id="CA2116" Action="Warning" />
            <Rule Id="CA2117" Action="Warning" />
            <Rule Id="CA2122" Action="Warning" />
            <Rule Id="CA2123" Action="Warning" />
            <Rule Id="CA2124" Action="Warning" />
            <Rule Id="CA2126" Action="Warning" />
            <Rule Id="CA2131" Action="Warning" />
            <Rule Id="CA2132" Action="Warning" />
            <Rule Id="CA2133" Action="Warning" />
            <Rule Id="CA2134" Action="Warning" />
            <Rule Id="CA2137" Action="Warning" />
            <Rule Id="CA2138" Action="Warning" />
            <Rule Id="CA2140" Action="Warning" />
            <Rule Id="CA2141" Action="Warning" />
            <Rule Id="CA2146" Action="Warning" />
            <Rule Id="CA2147" Action="Warning" />
            <Rule Id="CA2149" Action="Warning" />
            <Rule Id="CA2200" Action="Warning" />
            <Rule Id="CA2202" Action="Warning" />
            <Rule Id="CA2207" Action="Warning" />
            <Rule Id="CA2212" Action="Warning" />
            <Rule Id="CA2213" Action="Warning" />
            <Rule Id="CA2214" Action="Warning" />
            <Rule Id="CA2216" Action="Warning" />
            <Rule Id="CA2220" Action="Warning" />
            <Rule Id="CA2229" Action="Warning" />
            <Rule Id="CA2231" Action="Warning" />
            <Rule Id="CA2232" Action="Warning" />
            <Rule Id="CA2235" Action="Warning" />
            <Rule Id="CA2236" Action="Warning" />
            <Rule Id="CA2237" Action="Warning" />
            <Rule Id="CA2238" Action="Warning" />
            <Rule Id="CA2240" Action="Warning" />
            <Rule Id="CA2241" Action="Warning" />
            <Rule Id="CA2242" Action="Warning" />
            <Rule Id="CA1012" Action="Warning" />
        </Rules>
        <Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
            <Rule Id="SA1305" Action="Warning" />
            <Rule Id="SA1412" Action="Warning" />
            <Rule Id="SA1600" Action="None" />
            <Rule Id="SA1609" Action="Warning" />
        </Rules>
    </RuleSet>
    

    <PropertyGroup>
        <CodeAnalysisRuleSet>ca.ruleset</CodeAnalysisRuleSet>
    </PropertyGroup>
    

    {
      "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
      "settings": {
        "documentationRules": {
          "companyName": "YourCompanyName",
          "copyrightText": "Copyright (c) {companyName}. All Rights Reserved.\r\nLicensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.",
          "xmlHeader": false,
          "fileNamingConvention": "metadata"
        },
        "indentation": {
          "useTabs": true
        }
      }
    }
    

    <ItemGroup>
      <AdditionalFiles Include="stylecop.json" />
    </ItemGroup>
    

    DotNetAnalyzers/StyleCopAnalyzers

    .NET Core, Code Analysis and StyleCop

        7
  •  1
  •   Samuel Neff    16 年前