Usando isso via https://github.com/enginespot/js-beautify-sublime
Esperado:
.foo()
.bar();
Real:
.foo()
.bar();
Para ilustrar o problema: o recuo atual pode levar a EOFs como este:
});
});
})();
Isso me parece um erro e me levará a procurar a causa – ou pior, me deixará cego para os reais =(
Você poderia nos fornecer a entrada completa e a saída esperada, juntamente com sua configuração? Estou tendo dificuldade em correlacionar seu fragmento esperado (que parece incorreto, honestamente) com os blocos de fechamento. Obrigado!
Como muitas coisas nesta área, é claro que isso é uma questão de preferência e hábito pessoal, e não uma verdade objetiva.
Após o processamento, você pode ver algo assim:
(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 {};
}
]);
})();
Eu gostaria deste:
(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 {};
}
]);
})();
Esta é a minha configuração:
{
"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
O problema que você está falando é este travessão:
angular
.module('module', [])
Vou tirar um minuto para sentir um toque incrível por estarmos tão perto do que você quer ver. Em tempos passados, não teríamos chegado nem perto. :sorrir:
O recuo destina-se a manter a clareza de quais elementos fazem parte de uma declaração específica. No caso geral, o recuo é basicamente correto. Neste caso específico, você tem uma declaração muito longa, mas por #200 o embelezador não sabe que não há declarações significativas depois dessa. O embelezador não se destina a ser um formatador totalmente configurável - destina-se a abordar o caso geral
Para adicionar um pouco de profundidade a esta discussão, por favor, dê uma olhada nestes exemplos e diga-me como deve ser a formatação.
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()
Vou tirar um minuto para sentir um toque incrível por estarmos tão perto do que você quer ver.
Absolutamente! =)
Em relação ao recuo, acho que seu exemplo deve ficar assim:
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()
A máxima aqui é a mesma das chaves: início e fim devem estar no mesmo recuo. Além disso, as convenções de código de Douglas Crockford prescrevem o switch
da maneira que o fazem precisamente para evitar o recuo excessivo.
Exceto que js-beautify não segue o crockford por padrão, e se você executar o acima através do jslint, ele reclamará que .cooker(
está no recuo errado.
No seu exemplo, parece-me que é muito fácil para beta(zeta);
passar despercebido.
Além disso, você mostra alguns recuos em cadeia e outros não. Que lógica o embelezador deve usar para decidir quais recuam e quais não?
Vou deixar isso em aberto - o exemplo que você fornece parece ser baseado em AngularJS, então esse idioma pode ganhar maior aceitação ao longo do tempo. Mas não é algo que poderemos incorporar tão cedo.
Sinto muito: errei a indentação. Nenhum deles deveria ser recuado. E para beta(zeta);
não passar despercebido, eu usaria linhas vazias, assim:
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();
Como eu disse no início, acho que é uma questão de gosto pessoal. E especificamente com correntes de linha única, estou menos inclinado a reduzir o recuo. Mas acho o case multi-linha muito ruim e ter estilos mistos seria horrível, então eu definitivamente seguiria a estratégia de menos recuo, sempre.
Você pode olhar para # 485. Com esta próxima correção, o seguinte agora permanecerá inalterado quando passar pelo embelezador:
(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 {};
}]);
})();
Ainda não é o que você gostaria, mas o embelezador não forçará mais a declaração da função para uma nova linha (enquanto ainda respeita uma nova linha se você a incluir).
Eu tenho que marcar esta solicitação com +1, isso é especialmente útil ao trabalhar com Promises.
Promise.resolve()
.then(function() {
return foo.bar()
})
.then(function() {
return foo.baz();
})
.then(function() {
//...
}) //...
//...
Esse encadeamento pode continuar por um tempo, especialmente ao escrever um ponto final de API mais envolvido, e quando você está olhando para o fundo, é constantemente pego de surpresa com a forma como o recuo termina em relação a algo próximo.
Eu acredito que é importante que todo recuo de fechamento seja um nível de diferença de profundidade do próximo mais próximo.
:+1:
Eu acredito que é importante que todo recuo de fechamento seja um nível de diferença de profundidade do próximo mais próximo.
Para mim, este é o argumento decisivo que prova que o recuo extra é enganoso e, em última análise, um erro. Eu percebo que alguns podem sentir que há algum sentido em que
Promise.resolve()
.then(function() {
return foo.bar()
})
parece refletir que o then()
em algum sentido tem um relacionamento pai-filho com Promise.resolve()
, mas se isso for verdade, então cada then()
subsequente tem esse relacionamento com o anterior then()
. Claro que não existe realmente _no_ tal relacionamento pai-filho, e recuar como se houvesse todo o caminho faria uma grande bagunça, então ninguém faz isso. Mas recuar o primeiro then()
apenas faz uma _pequena_ bagunça em vez de uma enorme – é só que algumas pessoas parecem dispostas a tolerar essa pequena bagunça, enquanto alguns de nós preferem não ter _qualquer_ bagunça em nosso código se nós podemos ajudá-lo.
Pode ser bom ter a indicação visual que a indentação fornece, mas neste caso está sobrecarregando o significado da indentação – não apenas indicando um novo escopo, mas também indicando um método encadeado. No entanto, já temos o .
para indicar um método encadeado, e como o .
está no início do texto na linha, ele realmente fornece todo o (pseudo-)recuo necessário contanto que você esteja prestando atenção nele.
Portanto, não é _realmente_ _apenas _ uma questão de preferência pessoal – é uma questão de vantagens e desvantagens de ambas as abordagens. (É claro que a preferência pessoal _está_ envolvida, porque alguns podem não se importar com certas desvantagens ou benefícios, mas a discussão pode ser mais proveitosa se discutirmos quais são essas vantagens e desvantagens, em vez de apenas dizer "eu prefiro _x_" ou "eu prefira _y_".)
Eu acho que é forte o argumento de que as desvantagens da indentação extra são significativas, enquanto os benefícios podem ser obtidos de outra maneira.
Desvantagens do recuo extra para métodos encadeados:
Benefícios:
.
por si só fornece (MAS você _do_ obtém essa indicação com apenas um .
)+1
+1 Isso está levando a erros Expected exactly one space between '{a}' and '{b}'
no jslint.
Exemplo:
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('./'));
});
Erros:
4 Expected 'buffer' at column 9, not column 13. buffer: false
5 Expected '}' at column 5, not column 9. })
Maneira correta (para 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('./'));
});
Eu preferiria muito ter isso como uma opção, principalmente para evitar recuo extra desnecessário no encadeamento de promessas:
// 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 : ''));
});
Eu acho que o recuo extra é o equivalente a:
try {
// 4 spaces
} // 2
catch () {
// 4
}
Faz sentido se o token filho que envolve um bloco de recuo estiver em uma nova linha da variável inicial:
.module('module', function() {
// .module starts on new line, so this block has 2 indents
})
vs.
angular.module('module', function() {
// .module is on the same line as the initial variable angular, so this block has 1 indent
})
Mas se tudo pode caber em uma linha, o recuo duplo não deve acontecer.
(Como está, o acima seria linted/esperado como:)
angular.module('module', function() {
// double indent
});
Eu marquei isso como um aprimoramento.
Não estou argumentando contra ser uma boa ideia, só não tenho tempo.
Todos vocês "+1" e aqueles que comentaram, sintam-se à vontade para contribuir com um pull request.
+1 desejo
Eu abri um PR para isso
https://github.com/beautify-web/js-beautify/pull/927
se a integração contínua finalmente atualizar o status de PR, ela deverá estar pronta para mesclar.
+1 Isso é chato pra caramba
Comentários muito úteis
Eu tenho que marcar esta solicitação com +1, isso é especialmente útil ao trabalhar com Promises.
Esse encadeamento pode continuar por um tempo, especialmente ao escrever um ponto final de API mais envolvido, e quando você está olhando para o fundo, é constantemente pego de surpresa com a forma como o recuo termina em relação a algo próximo.
Eu acredito que é importante que todo recuo de fechamento seja um nível de diferença de profundidade do próximo mais próximo.