Skip to content

Commit

Permalink
Merge branch 'caleb/06-08-24/feat/style-library'
Browse files Browse the repository at this point in the history
  • Loading branch information
cfoust committed Aug 7, 2024
2 parents 1d6b924 + 110ffd0 commit 690928f
Show file tree
Hide file tree
Showing 27 changed files with 822 additions and 143 deletions.
15 changes: 15 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ For example:
}
```

#### Color

Some API functions, such as {{api style/render}}, accept colors as input. `cy` supports True Color colors specified in hexadecimal along with ANSI 16 and ANSI-256 colors. Under the hood, `cy` uses [charmbracelet/lipgloss](https://github.com/charmbracelet/lipgloss?tab=readme-ov-file#colors) and thus supports its color references.

You can read more about color support in terminal emiulators [here](https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#color-codes).

Examples of valid colors:

```janet
"#ffffff" # true color
"#123456" # true color
"255" # ANSI 256
"0" # ANSI 16
```

#### NodeID

Many API functions have a parameter of type `NodeID`, which can be one of two values:
Expand Down
48 changes: 48 additions & 0 deletions docs/src/layouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ A `:margins` node puts transparent margins around its child allowing the current
:cols 0 # number, optional
:rows 0 # number, optional
:border :rounded # border type, optional
:border-fg nil # color, optional
:border-bg nil # color, optional
:node {} # a node
}
```
Expand All @@ -130,6 +132,10 @@ These properties set the size of the node inside of the `:margins` node; they do

The [border style](#border-styles) for the borders around the node.

`:border-fg` and `:border-bg`

The foreground and background [color](/api.md#color) of the border.

`:node`

A valid layout node.
Expand All @@ -147,6 +153,8 @@ A `:split` node divides its visual space in two and gives it to two other nodes,
:cells nil # int or nil, optional
:percent nil # int or nil, optional
:border :rounded # border type, optional
:border-fg nil # color, optional
:border-bg nil # color, optional
:a {} # a node
:b {} # a node
}
Expand All @@ -164,6 +172,10 @@ At most one of these can be defined. Both determine the amount of space given to

The [border style](#border-styles) to use for the dividing line.

`:border-fg` and `:border-bg`

The foreground and background [color](/api.md#color) of the border.

`:a` and `:b`

Both must be valid layout nodes.
Expand All @@ -180,6 +192,8 @@ A `:borders` node surrounds its child in borders and adds an optional title to t
:title nil # string or nil, optional
:title-bottom nil # string or nil, optional
:border :rounded # border type, optional
:border-fg nil # color, optional
:border-bg nil # color, optional
:node {} # a node
}
```
Expand All @@ -192,6 +206,10 @@ These strings will be rendered on the top and the bottom of the window, respecti

The [border style](#border-styles) for this node. `:none` is not supported.

`:border-fg` and `:border-bg`

The foreground and background [color](/api.md#color) of the border.

`:node`

A valid layout node.
Expand All @@ -215,3 +233,33 @@ Some nodes have a `:border` property that determines the appearance of the node'
### Frames

The patterned background seen in the screenshot above is referred to as the **frame**. `cy` comes with a [range of different frames](/frames.md). You can choose between all of the available frames using the {{api action/choose-frame}} function, which is bound by default to {{bind :root ctrl+a F}}, and set the default frame on startup using the [`:default-frame`](/default-parameters.md#default-frame) parameter.

### Styling

{{story cast layout/styled}}

All string layout properties accept text styled with {{api style/render}} (or {{api style/text}}).

The layout shown in the monstrosity above was generated with the following code:

```janet
(def cmd1 (shell/new))
(def cmd2 (shell/new))
(layout/set
(layout/new
(margins
(split
(borders
(attach :id cmd1)
:border-fg "6"
:title (style/text "some pane" :fg "0" :bg "6")
:title-bottom (style/text "some subtitle" :fg "0" :bg "6"))
(borders
(pane :id cmd2)
:border-fg "5"
:title (style/text "some pane" :italic true :bg "5")
:title-bottom (style/text "some subtitle" :italic true :bg "5"))
:border-bg "3")
:cols 70
:border-bg "4")))
```
33 changes: 33 additions & 0 deletions pkg/cy/api/docs-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# doc: Render

(style/render style text)

Apply styling effects to some text. This function generates a string containing ANSI escape sequences that will style the provided `text` according to `style`.

All `cy` API functions that render text to the screen, such as {{api layout/set}} and {{api input/find}} accept input styled with {{api style/render}}.

`style` is a struct with any of the following properties:

- `:fg`: The foreground [color](/api.md#color) of the text.
- `:bg`: The background [color](/api.md#color) of the text.
- `:width`: The number of horizontal cells the text should occupy. Padding is added if this value exceeds the length of `text`.
- `:height`: The number of vertical cells the text should occupy. Padding is added if this value exceeds the height of `text`.
- `:align-horizontal`: One of `:left`, `:center`, or `:right`. If `:width` is greater than the length of the text, the text will be aligned according to this property.
- `:align-vertical`: One of `:top`, `:center`, or `:bottom`. If `:height` is greater than the height of the text, the text will be aligned according to this property.
- `:bold`: A boolean indicating whether the text should be bolded.
- `:italic`: A boolean indicating whether the text should be italic.
- `:underline`: A boolean indicating whether the text should be underlined.
- `:strikethrough`: A boolean indicating whether the text should be struck through.
- `:reverse`: A boolean indicating whether the foreground and background colorshould be reversed.
- `:blink`: A boolean indicating whether the text should blink.
- `:faint`: A boolean indicating whether the text should be faint.

For example:

```janet
(style/render
{:bg "4"
:bold true
:width 15
} "some text")
```
9 changes: 9 additions & 0 deletions pkg/cy/api/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,12 @@ var _ janet.Documented = (*LayoutModule)(nil)
func (l *LayoutModule) Documentation() string {
return DOCS_LAYOUT
}

//go:embed docs-style.md
var DOCS_STYLE string

var _ janet.Documented = (*StyleModule)(nil)

func (s *StyleModule) Documentation() string {
return DOCS_STYLE
}
8 changes: 2 additions & 6 deletions pkg/cy/api/layout_test.janet
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@
(layout/set layout)
(assert (deep= (layout/get) layout)))

(pp (layout/new (split
(pane)
(vsplit
(margins (attach))
(borders (pane))))))

(test "borders"
(do
(def layout (layout/new (split (attach) (pane)
Expand Down Expand Up @@ -56,6 +50,8 @@
{:type :split
:vertical true
:percent 26
:border-fg "7"
:border-bg "7"
:a {:type :pane :attached true}
:b {:type :pane}})

Expand Down
12 changes: 12 additions & 0 deletions pkg/cy/api/style.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package api

import (
"github.com/cfoust/cy/pkg/style"
)

type StyleModule struct {
}

func (s *StyleModule) Render(style *style.Style, text string) string {
return style.Render(text)
}
6 changes: 6 additions & 0 deletions pkg/cy/api/style_test.janet
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(test "render"
(style/render {:fg "#0000ff"
:bg "#ff0000"
:width 15
:italic true
:align-horizontal :right} "test"))
31 changes: 21 additions & 10 deletions pkg/cy/boot/layout.janet
Original file line number Diff line number Diff line change
Expand Up @@ -52,55 +52,66 @@ For example:
(defn
layout/split
```Convenience function for creating a new split node.```
[a b &named vertical cells percent border]
[a b &named vertical cells percent border border-fg border-bg]
(default vertical false)
{:type :split
:a a
:b b
:vertical vertical
:cells cells
:percent percent
:border border})
:border border
:border-fg border-fg
:border-bg border-bg})

(defn
layout/vsplit
```Convenience function for creating a new vertical split node.```
[a b &named cells percent border]
[a b &named cells percent border border-fg border-bg]
(layout/split a b
:vertical true
:cells cells
:percent percent
:border border))
:border border
:border-fg border-fg
:border-bg border-bg))

(defn
layout/hsplit
```Convenience function for creating a new horizontal split node.```
[a b &named cells percent border]
[a b &named cells percent border border-fg border-bg]
(layout/split a b
:vertical false
:cells cells
:percent percent
:border border))
:border border
:border-fg border-fg
:border-bg border-bg))

(defn
layout/margins
```Convenience function for creating a new margins node.```
[node &named cols rows border]
[node &named cols rows border border-fg border-bg]
{:type :margins
:node node
:cols cols
:rows rows
:border border})
:border border
:border-fg border-fg
:border-bg border-bg})

(defn
layout/borders
```Convenience function for creating a new borders node.```
[node &named title title-bottom border]
[node &named title title-bottom border border-fg border-bg]
{:type :borders
:node node
:title title
:title-bottom title-bottom
:border border})
:border border
:border-fg border-fg
:border-bg border-bg})


(defmacro
layout/new
Expand Down
41 changes: 41 additions & 0 deletions pkg/cy/boot/style.janet
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
(defn
style/text
````Style the provided text with the attributes provided. This function is a convenient wrapper around {{api style/render}}; instead of providing a struct, you may pass any of the attributes {{api style/render}} supports as named parameters.
For example:
```janet
(style/text "foobar" :bg "#00ff00")
(style/text "foobar" :italic true :bold true :width 15)
```
````
[text
&named
fg
bg
width
height
align-horizontal
align-vertical
bold
italic
underline
strikethrough
reverse
blink
faint]

(style/render
{:fg fg
:bg bg
:width width
:height height
:align-horizontal align-horizontal
:align-vertical align-vertical
:bold bold
:italic italic
:underline underline
:strikethrough strikethrough
:reverse reverse
:blink blink
:faint faint}
text))
2 changes: 2 additions & 0 deletions pkg/cy/janet.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (c *Cy) initJanet(ctx context.Context) (*janet.VM, error) {
TimeBinds: c.timeBinds,
CopyBinds: c.copyBinds,
},
"style": &api.StyleModule{},
"tree": &api.TreeModule{Tree: c.tree},
"viewport": &api.ViewportModule{},
}
Expand All @@ -61,6 +62,7 @@ func (c *Cy) initJanet(ctx context.Context) (*janet.VM, error) {
// like 01_actions.janet, 02_layout.janet is ugly
files := []string{
"actions.janet",
"style.janet",
"layout.janet",
"binds.janet",
}
Expand Down
29 changes: 29 additions & 0 deletions pkg/cy/stories.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,4 +584,33 @@ func init() {
`)
return screen, err
}, stories.Config{})

stories.Register("layout/styled", func(ctx context.Context) (
mux.Screen,
error,
) {
_, client, screen, err := createStory(ctx)
err = client.execute(`
(def cmd1 (shell/new))
(def cmd2 (shell/new))
(layout/set
(layout/new
(margins
(split
(borders
(attach :id cmd1)
:border-fg "6"
:title (style/text "some pane" :fg "0" :bg "6")
:title-bottom (style/text "some subtitle" :fg "0" :bg "6"))
(borders
(pane :id cmd2)
:border-fg "5"
:title (style/text "some pane" :italic true :bg "5")
:title-bottom (style/text "some subtitle" :italic true :bg "5"))
:border-bg "3")
:cols 70
:border-bg "4")))
`)
return screen, err
}, stories.Config{})
}
Loading

0 comments on commit 690928f

Please sign in to comment.