{"action":"created","issue":{"url":"https://api.github.com/repos/elves/elvish/issues/520","repository_url":"https://api.github.com/repos/elves/elvish","labels_url":"https://api.github.com/repos/elves/elvish/issues/520/labels{/name}","comments_url":"https://api.github.com/repos/elves/elvish/issues/520/comments","events_url":"https://api.github.com/repos/elves/elvish/issues/520/events","html_url":"https://github.com/elves/elvish/issues/520","id":278319983,"number":520,"title":"Make `edit:styled` more high-level and allow nesting","user":{"login":"xiaq","id":582021,"avatar_url":"https://avatars1.githubusercontent.com/u/582021?v=4","gravatar_id":"","url":"https://api.github.com/users/xiaq","html_url":"https://github.com/xiaq","followers_url":"https://api.github.com/users/xiaq/followers","following_url":"https://api.github.com/users/xiaq/following{/other_user}","gists_url":"https://api.github.com/users/xiaq/gists{/gist_id}","starred_url":"https://api.github.com/users/xiaq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xiaq/subscriptions","organizations_url":"https://api.github.com/users/xiaq/orgs","repos_url":"https://api.github.com/users/xiaq/repos","events_url":"https://api.github.com/users/xiaq/events{/privacy}","received_events_url":"https://api.github.com/users/xiaq/received_events","type":"User","site_admin":false},"labels":[{"id":871078641,"url":"https://api.github.com/repos/elves/elvish/labels/comp:ui","name":"comp:ui","color":"0e8a16","default":false},{"id":43633623,"url":"https://api.github.com/repos/elves/elvish/labels/type:enhancement","name":"type:enhancement","color":"0052cc","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2017-12-01T00:39:55Z","updated_at":"2018-05-29T11:02:46Z","closed_at":null,"author_association":"MEMBER","body":"Right now, `edit:styled` is tied to the terminal: There is a one-to-one relationship ([code](https://github.com/elves/elvish/blob/master/edit/ui/styled.go#L16)) mapping the supported styles to ANSI color sequences (`\"\\e[1;31m\"`, where `1;31` can be any semicolon-separated list of numbers), and it is possible to specify a number (or multiple numbers separated by semicolons) as the \"style\".\r\n\r\nThis is an improvement over writing ANSI color sequences by hand, but it still has a few drawbacks:\r\n\r\n1. It is tied to the terminal. In future, Elvish will support a web frontend where ANSI color sequences are not directly supported. It is possible to parse and convert them to CSS, but that is backwards. If we start with a high-level internal format, it can then support multiple presentations, including both ANSI color sequences and CSS.\r\n\r\n2. It does not support nesting. For instance, the ANSI color sequence for reverse video is `\"\\e[7m\"`. Two inverses cancel each other: so `echo (edit:styled (edit:styled lorem inverse) inverse)` should print `lorem` in normal style. However, without knowing the semantics of those different styles, it is not possible to compose them. Again, we can hack composing into the current implementation, but it is cleaner to do it from the source by having a semantics-based internal format.\r\n\r\nAnother minor thing is that since this function is useful outside editors, it is appropriate to put it in the builtin namespace, making the constructor `styled`.\r\n\r\nCurrent design is as follows:\r\n\r\n1.  A **styled text** is internally a list of **styled segments**; a segment is a string, combined with several attributes: `fg-color`, `bg-color`, `inverse`, `bold`, etc. It is possible to construct a segment with `styled-segment`, specifying the attributes as options, e.g. `styled-segment lorem &fg-color=red &bold=$true`. If the argument is already a styled segment, `styled-segment` copies it and modifies the specified attributes. Attributes of styled segments can be accessed like map elements, e.g. `$seg[bold]`.\r\n\r\n2.  It is possible to concatenate plain strings, styled segments and styled texts together: they will form a styled text that combines them, e.g. `echo (styled-segment lorem &fg-color=red)(styled-segment ipsum &inverse=$true)foobar`. No implicit whitespace is inserted between concatenated elements.\r\n\r\n3.  It is possible to apply **style transformers** to a piece of styled text. This uses the `styled` command, which accepts a plain string, a styled segment or styled text, and apply the transformer to all segments: e.g. `echo (styled (styled-segment lorem &fg-color=red)\" \"(styled-segment ipsum &inverse=$true) inverse)`. The `inverse` transformer **toggles** the `inverse` attribute, so that the result will be a red-and-inversed `lorem`, an inverse space, and and a normal `ipsum`.\r\n\r\n    A style transformer is simply a function that takes a styled segment and outputs another styled segment. For instance, the `inverse` transformer can be implemented as `[seg]{ styled-segment $seg &inverse=(not $seg[inverse]) }`. The mapping from the name to the implementation is kept in `$styled-transformer`. The default value implements all the styles supported by the current `edit:styled` implementation, like `bold`, `blue`, `bg-blue`.\r\n\r\n    In practice, this means that the user never has to use `styled-segment`, and the API of `styled` is backwards compatible with the current `edit:styled`."},"comment":{"url":"https://api.github.com/repos/elves/elvish/issues/comments/392737510","html_url":"https://github.com/elves/elvish/issues/520#issuecomment-392737510","issue_url":"https://api.github.com/repos/elves/elvish/issues/520","id":392737510,"user":{"login":"iwoloschin","id":6474586,"avatar_url":"https://avatars3.githubusercontent.com/u/6474586?v=4","gravatar_id":"","url":"https://api.github.com/users/iwoloschin","html_url":"https://github.com/iwoloschin","followers_url":"https://api.github.com/users/iwoloschin/followers","following_url":"https://api.github.com/users/iwoloschin/following{/other_user}","gists_url":"https://api.github.com/users/iwoloschin/gists{/gist_id}","starred_url":"https://api.github.com/users/iwoloschin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iwoloschin/subscriptions","organizations_url":"https://api.github.com/users/iwoloschin/orgs","repos_url":"https://api.github.com/users/iwoloschin/repos","events_url":"https://api.github.com/users/iwoloschin/events{/privacy}","received_events_url":"https://api.github.com/users/iwoloschin/received_events","type":"User","site_admin":false},"created_at":"2018-05-29T11:02:46Z","updated_at":"2018-05-29T11:02:46Z","author_association":"NONE","body":"If the end goal is to make colors appear the same in the terminal and via CSS it may make sense to not allow raw numbers, but instead use color names.  Unfortunately the color namespace is kind of broken:\r\n\r\nhttps://en.wikipedia.org/wiki/X11_color_names#Clashes_between_web_and_X11_colors_in_the_CSS_color_scheme"}}
{"actor":{"display_login":"iwoloschin"}}