cli
cli copied to clipboard
Variants of `col_` and `style_` functions that return bare strings
The attributes of cli_ansi_string
are a bit cumbersome for programming, they end up in unexpected places and cause issues for comparison, testing, etc.
These variants could be suffixed with _bare()
? We use the term "bare" in rlang and purrr for objects without attributes.
You mean the class
attribute? You can call as.character()
to drop that:
❯ attributes(col_red("red"))
$class
[1] "cli_ansi_string" "ansi_string" "character"
❯ as.character(col_red("red"))
[1] "\033[31mred\033[39m"
yes and the extra step either: makes it less likely to remember to remove the class; or makes the code harder to read.
Maybe so, but adding _bare
to all such functions will create ~60 more functions, which does not seem like a good idea, either.
Lots of packages add similar classes, e.g. glue. I think if the class attribute is in the way of snapshot tests, then we would ideally improve the snapshot tests.
yes and the glue class has been occasionally getting in the way as well. It's especially important not to leak these attributes when returning objects to users. Otherwise the returned class depends on implementation details.
How about a "col" and "style" constructor that would take enums of colour and styles? Then we'd only have 2 more functions.
Still, it is not a good idea to have extra exported functions, that essentially duplicate the functionality of the package, but behave differently. If you don't want the class in rlang, you can write a helper function that wraps cli functions, and drops it?
yes that is indeed what I did. I think it's strange that cli does not provide core/primitive functions (I don't see them as extra) to implement core behaviour without returning interactivity-facing classes. I can see we have a disagreement about API design so I'm closing this.
I think it is often better to provide a single api for task in a package. There is value in having a single way to do a task, at least with a certain package.
In general I do see the value in implementing things using "primitive" functions (see e.g. the very un-magical way callr::r()
takes an expression, which I am more and more happy with). But my feeling is that the current issues with ansi_string
do not warrant another API. I would hate to confuse people wrt which api to use when, and I suspect that I would also hate maintaining the two apis. Considering how much we use glue, and that glue also returns a classed string, and does not have a primitive method, makes me think that we can overcome the issues.
This said, I personally somewhat regret adding the ansi_string
class to cli. crayon does not have a class, and I added it to cli after requests from colleagues.