Js-beautify: последовательный отступ приводит к чрезмерному отступу

Созданный на 20 июн. 2014  ·  18Комментарии  ·  Источник: beautify-web/js-beautify

Используя это через https://github.com/enginespot/js-beautify-sublime

Ожидал:

.foo()
.bar();

Действительный:

  .foo()
  .bar();

Чтобы проиллюстрировать проблему: текущий отступ может привести к таким EOF:

      });
    });
})();

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

enhancement

Самый полезный комментарий

Я должен добавить +1 к этому запросу, это особенно удобно при работе с промисами.

Promise.resolve()
.then(function() {
  return foo.bar()
})
.then(function() {
  return foo.baz();
})
.then(function() {
 //...
}) //...
//...

Эта цепочка может продолжаться некоторое время, особенно при написании более сложной конечной точки API, и к тому времени, когда вы смотрите на нижнюю часть, вы постоянно застаете врасплох то, как заканчивается отступ относительно чего-то рядом.

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

Все 18 Комментарий

Не могли бы вы дать нам полный ввод и ожидаемый результат вместе с вашей конфигурацией? Мне трудно сопоставить ваш ожидаемый фрагмент (который, честно говоря, выглядит некорректно) с закрывающими блоками. Спасибо!

Как и многие вещи в этой области, это, конечно, вопрос личных предпочтений и привычек, а не объективная истина.

После обработки вы можете увидеть что-то вроде этого:

(function () {
    'use strict';

    angular
        .module('module', [])
        .directive('appVersion', ['version',
            function (version) {
                return function (scope, elm, attrs) {
                    elm.text(version);
                };
            }
        ])
        .directive('foo', [

            function () {
                return {};
            }
        ])
        .directive('bar', [

            function () {
                return {};
            }
        ]);
})();

Я хотел бы это:

(function () {
    'use strict';

    angular
    .module('module', [])
    .directive('appVersion', ['version',
        function (version) {
            return function (scope, elm, attrs) {
                elm.text(version);
            };
        }
    ])
    .directive('foo', [
        function () {
            return {};
        }
    ])
    .directive('bar', [
        function () {
            return {};
        }
    ]);
})();

Это моя конфигурация:

{
    "indent_level": 0,
    "indent_with_tabs": true,
    "preserve_newlines": true,
    "max_preserve_newlines": 5,
    "jslint_happy": true,
    "brace_style": "collapse",
    "keep_array_indentation": false,
    "keep_function_indentation": false,
    "space_before_conditional": true,
    "break_chained_methods": true,
    "eval_code": false,
    "unescape_strings": false,
    "wrap_line_length": 0,

    // jsbeautify options
    "format_on_save": true,
    "use_original_indentation": true
}

+1

Проблема, о которой вы говорите, - это один отступ:

    angular
        .module('module', [])

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

Отступ здесь предназначен для ясности, какие элементы являются частью конкретного утверждения. В общем случае отступ в основном правильный. В этом конкретном случае у вас есть одно очень длинное утверждение, но на # 200 бьютификатор не знает, что после него нет значимых утверждений. Beautifier не предназначен для полностью настраиваемого средства форматирования — он предназначен для решения общего случая.

Чтобы добавить немного глубины этому обсуждению, пожалуйста, взгляните на эти примеры и скажите мне, как должно выглядеть форматирование.

alpha
    .cooker(function() {
        some
            .thing()
            .should()
            .happen();
        elsewhere
            .some_other_thing()
            .should()
            .happen();
    })
    .thenclose()
beta(zeta);
omega
    .cage(function() {
        random
            .things()
            .should()
            .happen();
        elsewhere
            .some_other_thing()
            .should()
            .happen();
    })
    .thendie()

Я собираюсь воспользоваться минуткой, чтобы почувствовать прикосновение потрясающего, что мы так близки к тому, что вы хотите увидеть.

Абсолютно! знак равно

Что касается отступов, я думаю, ваш пример должен выглядеть так:

alpha
.cooker(function() {
    some
        .thing()
        .should()
        .happen();
    elsewhere
        .some_other_thing()
        .should()
        .happen();
})
.thenclose()
beta(zeta);
omega
.cage(function() {
    random
        .things()
        .should()
        .happen();
    elsewhere
        .some_other_thing()
        .should()
        .happen();
})
.thendie()

Принцип здесь тот же, что и для фигурных скобок: начало и конец должны быть на одном отступе. Кроме того, соглашения кода Дугласа Крокфорда предписывают switch именно так, как они делают, чтобы избежать чрезмерного отступа.

За исключением того, что js-beautify не следует за crockford по умолчанию, и если вы запустите вышеуказанное через jslint, он будет жаловаться, что .cooker( находится в неправильном отступе.

В вашем примере мне кажется, что beta(zeta); слишком легко упустить из виду.
Кроме того, вы показываете отступ некоторых последовательных цепочек, а некоторые нет. Какую логику должен использовать бьютификатор, чтобы решить, какие из них делают отступ, а какие нет?

Я собираюсь оставить это открытым — приведенный вами пример, похоже, основан на AngularJS, поэтому со временем эта идиома может получить более широкое признание. Но это не то, что мы сможем внедрить в ближайшее время.

Я ужасно извиняюсь: я испортил отступ. Ни один из них не должен был быть отступом. И чтобы beta(zeta); не упустили из виду, я бы использовал пустые строки, например:

alpha
.cooker(function() {
    some
    .thing()
    .should()
    .happen();

    elsewhere
    .some_other_thing()
    .should()
    .happen();
})
.thenclose();

beta(zeta);

omega
.cage(function() {
    random
    .things()
    .should()
    .happen();

    elsewhere
    .some_other_thing()
    .should()
    .happen();
})
.thendie();

Как я уже сказал в начале, я думаю, что это вопрос личного вкуса. И конкретно с однострочными цепочками я менее склонен уменьшать отступ. Но я нахожу многострочный случай очень плохим, и смешанные стили были бы ужасными, поэтому я определенно всегда придерживался бы стратегии меньшего отступа.

Вы можете посмотреть на # 485. С этим грядущим исправлением следующее останется неизменным при прохождении через улучшитель:

(function () {
    'use strict';

    angular
        .module('module', [])
        .directive('appVersion', ['version', function (version) {
            return function (scope, elm, attrs) {
                elm.text(version);
            };
        }])
        .directive('foo', [function () {
            return {};
        }])
        .directive('bar', [function () {
            return {};
        }]);
})();

Все еще не то, что вам хотелось бы, но бьютификатор больше не будет заставлять объявление функции переходить на новую строку (в то же время соблюдая новую строку, если вы ее включите).

Я должен добавить +1 к этому запросу, это особенно удобно при работе с промисами.

Promise.resolve()
.then(function() {
  return foo.bar()
})
.then(function() {
  return foo.baz();
})
.then(function() {
 //...
}) //...
//...

Эта цепочка может продолжаться некоторое время, особенно при написании более сложной конечной точки API, и к тому времени, когда вы смотрите на нижнюю часть, вы постоянно застаете врасплох то, как заканчивается отступ относительно чего-то рядом.

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

:+1:

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

Для меня это решающий аргумент, доказывающий, что дополнительные отступы вводят в заблуждение и, в конечном счете, являются ошибкой. Я понимаю, что некоторым может показаться, что есть некий смысл, в котором

Promise.resolve()
  .then(function() {
    return foo.bar()
  })

кажется, отражает то, что then() в некотором смысле имеет отношения родитель-потомок с Promise.resolve() , но если это верно, то каждый последующий then() имеет такое же отношение с предыдущий then() . Конечно, на самом деле таких отношений родитель-потомок _нет_, и отступы, как если бы они были полностью вниз, привели бы к большому беспорядку, поэтому никто этого не делает. Но отступ для первых then() просто создает _маленький_ беспорядок, а не огромный — просто некоторые люди, похоже, готовы мириться с этим небольшим беспорядком, в то время как некоторые из нас предпочитают не иметь _никаких_ беспорядков в нашем коде, если мы можем помочь.

Может быть приятно иметь визуальную индикацию, которую обеспечивают отступы, но в данном случае это перегружает смысл отступов — не только указывает на новую область, но и указывает на связанный метод. Однако у нас уже есть . для обозначения связанного метода, и поскольку . находится в начале текста в строке, он действительно обеспечивает все необходимые (псевдо)отступы. пока вы обращаете на это внимание.

Так что это не _на самом деле_ _просто _ вопрос личных предпочтений — это вопрос преимуществ и недостатков обоих подходов. (Конечно, речь идет о личных предпочтениях, поскольку некоторых могут не волновать определенные недостатки или определенные преимущества, но обсуждение может быть более плодотворным, если мы обсудим, в чем заключаются эти преимущества и недостатки, а не просто скажем: «Я предпочитаю _x_» или «Я предпочитаю _x_» или «Я предпочитаю _x_». предпочитаю _y_".)

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

Недостатки дополнительных отступов для цепных методов:

  • ваш отступ больше не является надежным индикатором области действия
  • ваша заключительная пунктуация, вероятно, заставит вас подумать, что вы сделали ошибку

Преимущества:

  • вы получаете большую визуальную индикацию цепочки методов, чем просто . сама по себе (НО вы _do_ получаете эту индикацию только с . )

+1

+1 Это приводит к ошибкам Expected exactly one space between '{a}' and '{b}' в jslint.

Пример:

gulp.task('changelog', function () {
    return gulp.src('CHANGELOG.md', {
            buffer: false
        })
        .pipe(conventionalChangelog({
            preset: 'angular' // Or to any other commit message convention you use.
        }))
        .pipe(gulp.dest('./'));
});

Ошибки:

4   Expected 'buffer' at column 9, not column 13.    buffer: false
5   Expected '}' at column 5, not column 9.  })

Правильный способ (для jslint):

gulp.task('changelog', function () {
    return gulp.src('CHANGELOG.md', {
        buffer: false
    })
        .pipe(conventionalChangelog({
            preset: 'angular' // Or to any other commit message convention you use.
        }))
        .pipe(gulp.dest('./'));
});

Я бы очень предпочел иметь это как вариант, в первую очередь, чтобы избежать ненужных дополнительных отступов в цепочке обещаний:

  // fetch `config.json` and then set as constant
  $http.get('config.json').then(function(response) {
    angular.module('myApp').constant('CONFIG', response.data);
  })
  .then(function() {
    angular.bootstrap(document, ['myApp']);
  })
  .catch(function(err) {
    var message = (err && err.data || err && err.message);
    console.error('Unable to bootstrap application.', err);
    window.alert('Unable to bootstrap application.' + (message ? '\n\n' + message : ''));
  });

Я думаю, что дополнительный отступ эквивалентен:

try {
    // 4 spaces
  } // 2
  catch () {
    // 4
  }

Это имеет смысл, если дочерний токен, который оборачивает блок отступа, находится в новой строке от исходной переменной:

    .module('module', function() {
      // .module starts on new line, so this block has 2 indents
    })

против.

  angular.module('module', function() {
    // .module is on the same line as the initial variable angular, so this block has 1 indent
  })

Но если все это может поместиться в одну строку, то двойного отступа быть не должно.

(В нынешнем виде приведенное выше будет выглядеть/ожидаться как:)

angular.module('module', function() {
    // double indent
  });

Я отметил это как улучшение.
Я не спорю с тем, что это хорошая идея, у меня просто нет времени.

Все, кто поставил +1, и те, кто прокомментировал, не стесняйтесь вносить запрос на вытягивание.

+1 хочу

Я открыл PR для этого

https://github.com/beautify-web/js-beautify/pull/927

если непрерывная интеграция, наконец, обновит статус PR, он должен быть готов к слиянию.

+1 Это чертовски скучно

Была ли эта страница полезной?
0 / 5 - 0 рейтинги