Есть ли способ принудительно использовать вкладки вместо пробелов?

StyleCop предлагает проверить постоянное использование пробелов, но, к сожалению, отсутствует противоположная идея: Использовать исходный код для использования вкладок. Есть ли способ добавить эту функциональность? Это не должно быть StyleCop, другие инструменты также приветствуются.

Ответ 1

Вы можете использовать StyleCop + для принудительного использования вкладок.

После загрузки StyleCopPlus.dll поместите его в папку Custom Rules внутри основной папки StyleCop C:\Program Files (x86)\StyleCop 4.7\Custom Rules или непосредственно в основной папке.

Теперь, когда вы открываете Settings.StyleCop с помощью StyleCopSettingsEditor, вы сможете установить правило SP2001: CheckAllowedIndentationCharacters.

Это правило можно найти на вкладке StyleCop+ под подтекстом More Custom Rules под заголовком Formatting:

Rule Options

Ответ 2

Я тоже человек с табуляторами, но есть много причин использовать один из них, и есть другие места, чтобы понять, почему вы считаете, что один лучше другого.:)

На самом деле я хотел получить то же самое - правило для проверки вкладок вкладок - поэтому я написал его на основе источника SpacingRules от StyleCop. Кажется, он работает достаточно хорошо, хотя я использовал его только в нескольких проектах. Возможно, это будет оптимизировано или что-то еще... но оно работает.

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 файл "SpacingRules.xml" в сборке вместе с этой штукой. (Подробнее читайте в документе StyleCop SDK.)

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

Одна вещь, которую вы могли бы сделать, предполагая, что вы используете Visual Studio в качестве вашей среды IDE, и что ваш приятель по команде для этой идеи должен был бы установить VS для использования вкладок вместо пробелов, экспорта и совместного использования файла настроек.

Этот параметр можно найти в разделе "Инструменты" > "Параметры" > "Текстовый редактор" > "Все языки" (или язык, который вы хотите использовать) > "Вкладки", а затем с правой стороны вы можете выбрать "Вставить пробелы" или "Сохранить вкладки".

Чтобы экспортировать настройки из вашей визуальной студии: Инструменты > Параметры импорта и экспортa > Экспортировать выбранные настройки среды > выберите "Параметры"

Просто мысль - но, честно говоря, реальная проблема - это бай-ин от ваших товарищей по команде. В противном случае они могут вернуться к своим настройкам. Кроме того, при регистрации, как предложил Сэм, вы можете сделать автоматическое повторное форматирование.

НТН

Ответ 4

StyleCop поддерживает создание настраиваемых правил, поэтому вы можете добавить собственное правило "использовать ведущие вкладки вместо пространства". Если вам не хочется разрабатывать свои собственные, вы можете получить существующее правило либо в http://stylecopcontrib.codeplex.com/, либо http://github.com/AArnott/nerdbank.stylecop.rules.

Ответ 5

Хорошо мне удалось выяснить проблему, потому что причина появления этого предупреждения появляется, появляется потому, что разработчик иногда копирует и вставляет код

если вы используете VS2010 Перейти к редактору решений Проверка настройки стиля Cop затем измените настройку в стиле Cop, например, отключите или снимите флажок [Интервал.....]

Ответ 6

Сделайте это на своем сервере управления версиями. Используйте pre-commit script, чтобы проверить файл для строк, начинающихся с нескольких пробелов, и предотвратить фиксацию.

Я согласен, что вкладки лучше, чем пробелы. Это личное предпочтение, но последовательность команд очень важна.