-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Console] Make pretty the box
style table
#25456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before making more changes, let's wait and see if others agree with this feature. But if they agree, we should decided if we make all separators configurable (i.e. horizontal and vertical borders).
In other libraries (e.g. https://github.com/Automattic/cli-table) they define these chars:
chars: {
'top': '─'
, 'top-mid': '┬'
, 'top-left': '┌'
, 'top-right': '┐'
, 'bottom': '─'
, 'bottom-mid': '┴'
, 'bottom-left': '└'
, 'bottom-right': '┘'
, 'left': '│'
, 'left-mid': '├'
, 'mid': '─'
, 'mid-mid': '┼'
, 'right': '│'
, 'right-mid': '┤'
, 'middle': '│'
}
* | ||
* @return $this | ||
*/ | ||
public function setCrossingChars(string $cross, string $topLeft = null, string $topMiddle = null, string $topRight = null, string $middleRight = null, string $bottomRight = null, string $bottomMiddle = null, string $bottomLeft = null, string $middleLeft = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of string $topLeft = null
you can use ?string $topLeft
because in master we use PHP 7.1, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not the same meaning in fact. I want to make optional these params.
function f(?string $p) {}
f(); // Uncaught Error: Too few arguments to function f(), 0 passed in...
* | ||
* @return string $crossingTopRightChar | ||
*/ | ||
public function getCrossingTopRightChar() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return type-hints in these methods?
public function getCrossingTopRightChar(): string { ... }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it would be better, but the others getters of this class don't have return type-hints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a big deal IMO, let's use new PHP features in new code
edit: I mean, let's add typehints for the newly added methods :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@javiereguiluz Indeed, my current implementation provides only an unique style. The library which you mentionned allow to apply a different style between outside and inside borders. That doesn't look essential, but I like it. It can be useful for rendering a thinner separateur in the rows. I'm +1. |
The new style looks much better than the initial one. Looks great! |
6ebc50d
to
d7eec74
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome 👍
? array($this->style->getCrossingMidLeftChar(), $this->style->getCrossingChar(), $this->style->getCrossingMidRightChar()) | ||
: (self::SEPARATOR_TOP === $type | ||
? array($this->style->getCrossingTopLeftChar(), $this->style->getCrossingTopMidChar(), $this->style->getCrossingTopRightChar()) | ||
: array($this->style->getCrossingBottomLeftChar(), $this->style->getCrossingBottomMidChar(), $this->style->getCrossingBottomRightChar())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this nesting of ternary operators are hard to read IMO. I suggest using a if/elseif/else
instead (and btw, this will also avoid the need to allocate arrays holding values just to unpack it immediately)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it better now?
* </code> | ||
* | ||
* @param string $cross Crossing char (see #0 of example) | ||
* @param string|null $topLeft Top left char (see #1 of example), equal to $cross if undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if null
. there is no undefined
in PHP (E_TOO_MUCH_JAVASCRIPT 😄 ?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
d7eec74
to
a3f71c0
Compare
* Gets crossing top right char. | ||
* | ||
* @return string $crossingTopRightChar | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably added it for consistency, but please remove this docblock as it does not give more info than the signature itself, same for next ones below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was for consistency with others methods. Docblocks removed.
@@ -132,6 +139,127 @@ public function getCrossingChar() | |||
return $this->crossingChar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should deprecate getCrossingChar()
and setCrossingChar()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I deprecated setCrossingChar()
. But not the getter which is always used as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the point of a deprecation. Update the calls and trigger a deprecation message. :}
* | ||
* @return $this | ||
*/ | ||
public function setCrossingChars(string $cross, string $topLeft = null, string $topMid = null, string $topRight = null, string $midRight = null, string $bottomRight = null, string $bottomMid = null, string $bottomLeft = null, string $midLeft = null): self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo I would rather use ?string
as @javiereguiluz said (or even not nullable string
) and not take crossingChar
. This methid should be called with $this->setCrossingChars($cross, $cross, ...);
(and thus slowly deprecate crossingChar
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure to understand why use nullable string here... Could you to be more accurate please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because ?string $topLeft
looks better than string $topLeft = null
, it's more concise, and the ?string
feature was introduced in modern PHP versions precisely to avoid doing string ... = null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmh I'm not sure that ?string $topLeft
replaces string $topLeft = null
. ?string
simply allows string
and null
value, but it doesn't set a null default value.
function f(?string $p) {}
f(); // Uncaught Error: Too few arguments to function f(), 0 passed in...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More info here: http://php.net/manual/en/migration71.new-features.php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum, didn't see the 0
in the schema, so my bad for the removal. But I still think that allowing a null
value for the rest is not really good, and you should specify a value for all these other edges.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, you CAN use the crossingChar
for ALL the edges, but it shouldn't be implied if no value is given. Hence the "not allowing null values", so nothing too implicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
allowing a null value for the rest is not really good
I think that the first param $crossingChar
can be used as generic crossing char:
$style->setCrossingChars('+');
// vs
$style->setCrossingChars('+', '+', '+', '+', '+', '+', '+', '+', '+');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd add this method above getCrossingChar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ro0NL Moved.
650c922
to
a701379
Compare
*/ | ||
public function setCrossingChar($crossingChar) | ||
{ | ||
@trigger_error(sprintf('%s() is deprecated since version 4.1 and will be removed in 5.0. Use setCrossingChars() instead.', __METHOD__), E_USER_DEPRECATED); | ||
|
||
$this->crossingChar = $crossingChar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should call $this->setCrossingChars($crossingChar);
to update all properties
perhaps consider to not deprecate this method and make args in setCrossingChars required instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Oups, bad rebase. It's fixed.
- Personally I prefer with optional args. Does this [Console] Make pretty the
box
style table #25456 (comment) convince you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmh finally, I have changed my opinion :) I think that setCrossingChar()
can be conserved and used as a shortcut of setCrossingChars()
. Moreover, that simplifies a lot this PR. Could you check my second commit? If you disagree, I can remote it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you keeo the setCrossingChar
, then maybe you should add setTopLeft
, and so on. And then get rid of setCrossingChars
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. If you don't use a generic crossing char by setting setCrossingChar(), you have to set all kinds of crossing char. And it's better if we can do it with only 1 call of setCrossingChars() instead 9 different calls (1 cross + 4 corners + 4 mids).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the idea of this PR to deprecate the "generic crossing char", in favor of using the specific ones ? The setCorssingChar
should be imo just for the 0
(any "crossroad" delimiters). Using it as a generic should be deprecated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was. But the #25456 (comment) of @ro0NL looks relevant:
// we can set specific chars:
setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├');
// and we could also set generic char (useful for no-unicode):
setCrossingChar('+');
// without this last one, we should write:
setCrossingChars('+', '+', '+', '+', '+', '+', '+', '+', '+');
* | ||
* @return $this | ||
*/ | ||
public function setCrossingChars(string $cross, string $topLeft = null, string $topMid = null, string $topRight = null, string $midRight = null, string $bottomRight = null, string $bottomMid = null, string $bottomLeft = null, string $midLeft = null): self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd add this method above getCrossingChar
a701379
to
3e6d1e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
┌─────────────┐
| lookin good |
└─────────────┘
*/ | ||
public function setCrossingChar($crossingChar) | ||
{ | ||
$this->crossingChar = $crossingChar; | ||
@trigger_error(sprintf('%s() is deprecated since version 4.1 and will be removed in 5.0. Use setCrossingChars() instead.', __METHOD__), E_USER_DEPRECATED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method "%s()" is ...
(note the quotes.. we want those :))
(@ro0NL For generating your message review, I hope that you have used: (new Table(new ConsoleOutput()))->setStyle('box')->setRows([['lookin good']])->render(); 😄) |
@stof Do we need more changes with this PR? |
60f0c80
to
f60296d
Compare
Does this PR need some work still? (Travis failure not related) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor comments :)
*/ | ||
public function setCrossingChar($crossingChar) | ||
{ | ||
$this->crossingChar = $crossingChar; | ||
@trigger_error(sprintf('%s() is deprecated since Symfony 4.1 and will be removed in 5.0. Use setDefaultCrossingChar() instead.', __METHOD__), E_USER_DEPRECATED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method "%s()" is ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/** | ||
* Sets crossing character. | ||
* | ||
* @param string $crossingChar | ||
* | ||
* @return $this | ||
* | ||
* @deprecated since Symfony 4.1, to be removed in 5.0. Use {@link setDefaultCrossingChar()} instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{@link method()}
renders OK after compile? not sure it's needed / consistent:
https://github.com/symfony/symfony/search?l=PHP&q=%40deprecated+use+instead&type=&utf8=%E2%9C%93
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(annex comment: {@link method()}
is not rendered on api.symfony.com. E.g. https://api.symfony.com/3.4/Symfony/Bundle/SecurityBundle/Security/FirewallContext.html#method_getContext)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove the @link here as we've never done that before elsewhere AFAIK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's quite used in fact (e.g. on 3.4, more than 300 occurrences whose 13 in a @deprecated
annotation) and it makes sense here IMO. Sure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok let's keep like this then :)
f60296d
to
528eacd
Compare
@@ -132,6 +194,46 @@ public function getCrossingChar() | |||
return $this->crossingChar; | |||
} | |||
|
|||
public function getCrossingTopRightChar(): string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need these getters? I can't picture a use case for these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @ostrolucky, I would remove all the getters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But getters are used in Table class for rendering, they can't be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fear I'll might be the only one, but I'd rather use a single getter to get them all at once (from topLeft to midLeft).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for @ogizanagi's idea. And let's mark it as internal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this new style works on all OSes (including Windows), I would switch the default table theme to the new one.
* Sets crossing characters. | ||
* | ||
* Example: | ||
* <code> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not using HTML in desc, so this should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<code>
tag is sometimes used yes (on master, 17 occurrences). This code-description can be useful IMO.
* @param string $bottomLeft Bottom left char (see #7 of example) | ||
* @param string $midLeft Mid left char (see #8 of example) | ||
* | ||
* @return $this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be removed as the method signature already document this explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/** | ||
* Sets crossing character. | ||
* | ||
* @param string $crossingChar | ||
* | ||
* @return $this | ||
* | ||
* @deprecated since Symfony 4.1, to be removed in 5.0. Use {@link setDefaultCrossingChar()} instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove the @link here as we've never done that before elsewhere AFAIK.
@@ -132,6 +194,46 @@ public function getCrossingChar() | |||
return $this->crossingChar; | |||
} | |||
|
|||
public function getCrossingTopRightChar(): string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @ostrolucky, I would remove all the getters.
It's supposed to work with DOS too (cf https://en.wikipedia.org/wiki/Box-drawing_character#DOS).
Yes! But switching to the new theme breaks some tests and it's more complicated than expected. I suggest to do that in an another PR. |
528eacd
to
59f8464
Compare
*/ | ||
public function setCrossingChar($crossingChar) | ||
{ | ||
$this->crossingChar = $crossingChar; | ||
@trigger_error(sprintf('Method %s() is deprecated since Symfony 4.1 and will be removed in 5.0. Use setDefaultCrossingChar() instead.', __METHOD__), E_USER_DEPRECATED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and will be removed in 5.0
should be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
59f8464
to
41f52b3
Compare
Thank you @maidmaid. |
This PR was merged into the 4.1-dev branch. Discussion ---------- [Console] Make pretty the `box` style table | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | / | License | MIT | Doc PR | / The console component is the 2nd most popular Symfony component with 70M of downloads. I think such composant has to provide faultless tables, with perfect management of borders, especially since the new `box` style table has been merged (cf #25301).  Commits ------- 41f52b3 Make pretty the `box` style table
@maidmaid This looks absolutely amazing! I'm excited to see more feature/improvement changes for the console component's output handling; this is an excellent addition. Thanks for the work to get it done! |
This PR was merged into the 4.1-dev branch. Discussion ---------- [Console] Add box-double table style | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony/symfony#25456 (review) | License | MIT | Doc PR | / In symfony/symfony#25456 (review) @javiereguiluz suggested to have a complete configuration for style table. It was a nice idea, but not yet implemented. The box-drawing characters allow to combine different styles (like double/single lines). This PR give the possibility to use them. The previous symfony/symfony#25456 introduced the box-drawing characters; this PR exploits all their strength.  See https://gist.github.com/maidmaid/3eb55afc4f2857cae89d7ac43d7943ae for some examples. Commits ------- 463f986c28 Add box-double table style
This PR was merged into the 4.1-dev branch. Discussion ---------- [Console] Add box-double table style | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #25456 (review) | License | MIT | Doc PR | / In #25456 (review) @javiereguiluz suggested to have a complete configuration for style table. It was a nice idea, but not yet implemented. The box-drawing characters allow to combine different styles (like double/single lines). This PR give the possibility to use them. The previous #25456 introduced the box-drawing characters; this PR exploits all their strength.  See https://gist.github.com/maidmaid/3eb55afc4f2857cae89d7ac43d7943ae for some examples. Commits ------- 463f986 Add box-double table style
The console component is the 2nd most popular Symfony component with 70M of downloads. I think such composant has to provide faultless tables, with perfect management of borders, especially since the new
box
style table has been merged (cf #25301).