Custom Widget Docs Improvements (#1225)

Goes into more detail and includes different types of widgets
This commit is contained in:
Sylvie Crowe 2024-11-07 14:30:08 -08:00 committed by GitHub
parent 276e078b3b
commit cf71380072
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 192 additions and 34 deletions

View File

@ -6,16 +6,48 @@ title: "Custom Widgets"
# Custom Widgets
Wave allows users to create their own widgets to uniquely customize their experience for what works for them. While we plan on greatly expanding on this in the future, it is already possible to make terminal/cli widgets that you can access at the press of a button.
Wave allows users to create their own widgets to uniquely customize their experience for what works for them. While we plan on greatly expanding on this in the future, it is already possible to make some widgets that you can access at the press of a button. All widgets can be created by modifying the `<WAVETERM_HOME>/config/widgets.json` file.
## The Structure of a Widget
All widgets share a similar structure that roughly looks like the example below:
```json
"<widget name>": {
"icon": "<fontawesome icon name>",
"label": "<the text label of the widget>",
"color": "<the color of the label>",
"blockdef": {
"meta": {
"view": "term",
"controller": "cmd",
"cmd": "<the actual cli command>"
}
}
}
```
This consists of a couple different parts. First and foremost, each widget has a unique identifying name. The value associated with this name is the outer `WidgetConfigType`. It is outlined in red below:
This `WidgetConfigType` is shared between all types of widgets. That is to say, all widgets&mdash;regardless of type&mdash; will use the same keys for this. The accepted keys are:
| Key | Description |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| "display:order" | (optional) Overrides the order of widgets with a number in case you want the widget to be different than the order provided in the `widgets.json` file. Defaults to 0. |
| "icon" | (optional) The name of a fontawesome icon. Defaults to `"browser"`. |
| "color" | (optional) A string representing a color as would be used in CSS. Hex codes and custom CSS properties are included. This defaults to `"var(--secondary-text-color)"` which is a color wave uses for text that should be differentiated from other text. Out of the box, it is `"#c3c8c2"`. |
| "label" | (optional) A string representing the label that appears underneath the widget. It will also act as a tooltip on hover if the `"description"` key isn't filled out. It is null by default. |
| "description" | (optional) A description of what the widget does. If it is specified, this serves as a tooltip on hover. It is null by default. |
| "blockdef" | This is where the the non-visual portion of the widget is defined. Note that all further definition takes place inside a meta object inside this one. |
The other options are part of the inner `MetaTSType`. This contains all of the details about how the widget actually works. The valid keys vary with each type of widget. They will be individually explored in more detail below.
![An example of a widget with outer keys labeled as WidgetConfigType and inner keys labeled as MetaTSType. In the example, the outer keys are icon, label, color, and blockdef. The inner keys are view, controller, and cmd.](/img/widget-example.png)
# Terminal and CLI Widgets
A terminal widget, or CLI widget, is a widget that simply opens a terminal and runs a CLI command.
These widgets are managed in the `~/.config/waveterm/widgets.json` file.
A terminal widget, or CLI widget, is a widget that simply opens a terminal and runs a CLI command. They tend to look something like the example below:
## Designing a Widget
Each widget is a key-value pair of a json object where the key is the name of the widget, and the value is an object responsible for configuring the widget. As a whole, it looks like:
```json
{
<... other widgets go here ...>,
@ -34,41 +66,31 @@ Each widget is a key-value pair of a json object where the key is the name of th
<... other widgets go here ...>
}
```
In essence, there are two places that require customization. The first is the outer `WidgetConfigType` which is directly in the object that corresponds with the widget name. In the example above, it contains `"icon"`, `"label"`, and `"color"`. Valid options for this type include:
| Key | Description |
|-----|-------------|
|"display:order"| (optional) Overrides the order of widgets with a number in case you want the widget to be different than the order provided in the `widgets.json` file. Defaults to 0. |
|"icon"| (optional) The name of a fontawesome icon. Defaults to `"browser"`.|
|"color"| (optional) A string representing a color as would be used in CSS. Hex codes and custom CSS properties are included. This defaults to `"var(--secondary-text-color)"` which is a color wave uses for text that should be differentiated from other text. Out of the box, it is `"#c3c8c2"`.|
|"label"| (optional) A string representing the label that appears underneath the widget. It will also act as a tooltip on hover if the `"description"` key isn't filled out. It is null by default.|
|"description"| (optional) A description of what the widget does. If it is specified, this serves as a tooltip on hover. It is null by default.|
|"blockdef"| This is where the the non-visual portion of the widget is defined. Note that all further definition takes place inside a meta object inside this one.|
The `WidgetConfigType` takes the usual options common to all widgets. The `MetaTSType` can include the keys listed below:
The other part to configure is the `MetaTSType` associated with the widget. The topic of the `MetaTSType` is vast and deserves it's own documentation, but here is a subset that is relevant to creating terminal widgets.
| Key | Description |
|-----|-------------|
| "view" | A string that specifies the general type of widget. In the case of custom terminal widgets, this must be set to `"term"`.|
| "controller" | A string that specifies the type of command being used. For more persistent shell sessions, set it to "shell". For one off commands, set it to "cmd". Note that it is often possible to achieve the same result through each depending on the command being used.|
| "cmd" | (optional) When the `"controller"` is set to `"cmd"`, this option provides the actual command to be run. Note that because it is run as a command, there is no shell session unless you are launching a command that contains a shell session itself. Defaults to an empty string. |
| "cmd:interactive" | (optional) When the `"controller"` is set to `"term", this boolean adds the interactive flag to the launched terminal. Defaults to false.|
| "cmd:login" | (optional) When the `"controller"` is set to `"term"`, this boolean adds the login flag to the term command. Defaults to false.|
| "cmd:runonstart" | (optional) The command will rerun when the app is started. Without it, you must manually run the command. Defaults to true.|
| "cmd:clearonstart" | (optional) When the cmd starts, the contents of the block are cleared out. Defaults to false. |
| "cmd:clearonrestart" | (optional) When the app restarts, the contents of the block are cleared out. Defaults to false. |
| "cmd:env" | (optional) A key-value object represting environment variables to be run with the command. Currently only works locally. Defaults to an empty object. |
| "cmd:cwd" | (optional) A string representing the current working directory to be run with the command. Currently only works locally. Defaults to the home directory. |
| "cmd:nowsh" | (optional) A boolean that will turn off wsh integration for the command. Defaults to false. |
| "term:localshellpath" | (optional) Sets the shell used for running your widget command. Only works locally. If left blank, wave will determine your system default instead. |
| "term:localshellopts" | (optional) Sets the shell options meant to be used with `"term:localshellpath"`. This is useful if you are using a nonstandard shell and need to provide a specific option that we do not cover. Only works locally. Defaults to an empty string. |
| Key | Description |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "view" | A string that specifies the general type of widget. In the case of custom terminal widgets, this must be set to `"term"`. |
| "controller" | A string that specifies the type of command being used. For more persistent shell sessions, set it to "shell". For one off commands, set it to "cmd". Note that it is often possible to achieve the same result through each depending on the command being used. |
| "cmd" | (optional) When the `"controller"` is set to `"cmd"`, this option provides the actual command to be run. Note that because it is run as a command, there is no shell session unless you are launching a command that contains a shell session itself. Defaults to an empty string. |
| "cmd:interactive" | (optional) When the `"controller"` is set to `"term", this boolean adds the interactive flag to the launched terminal. Defaults to false. |
| "cmd:login" | (optional) When the `"controller"` is set to `"term"`, this boolean adds the login flag to the term command. Defaults to false. |
| "cmd:runonstart" | (optional) The command will rerun when the app is started. Without it, you must manually run the command. Defaults to true. |
| "cmd:clearonstart" | (optional) When the cmd starts, the contents of the block are cleared out. Defaults to false. |
| "cmd:clearonrestart" | (optional) When the app restarts, the contents of the block are cleared out. Defaults to false. |
| "cmd:env" | (optional) A key-value object represting environment variables to be run with the command. Currently only works locally. Defaults to an empty object. |
| "cmd:cwd" | (optional) A string representing the current working directory to be run with the command. Currently only works locally. Defaults to the home directory. |
| "cmd:nowsh" | (optional) A boolean that will turn off wsh integration for the command. Defaults to false. |
| "term:localshellpath" | (optional) Sets the shell used for running your widget command. Only works locally. If left blank, wave will determine your system default instead. |
| "term:localshellopts" | (optional) Sets the shell options meant to be used with `"term:localshellpath"`. This is useful if you are using a nonstandard shell and need to provide a specific option that we do not cover. Only works locally. Defaults to an empty string. |
## Example Widgets
## Example Terminal Widgets
Here are a few simple widgets to serve as examples.
Suppose I want a widget that will run speedtest-go when opened. Then, I can define a widget as
```json
{
<... other widgets go here ...>,
@ -87,9 +109,11 @@ Suppose I want a widget that will run speedtest-go when opened. Then, I can defi
<... other widgets go here ...>
}
```
Using `"cmd"` for the `"controller"` is the simplest way to accomplish this. `"cmd:clearonstart"` isn't necessary, but it makes it so every time the command is run (which can be done by right clicking the header and selecting `Force Controller Restart`), the previous contents are cleared out.
Now suppose I wanted to run a TUI app, for instance, `dua`. Well, it turns out that you can more or less do the same thing:
```json
<... other widgets go here ...>,
"dua" : {
@ -105,4 +129,138 @@ Now suppose I wanted to run a TUI app, for instance, `dua`. Well, it turns out t
},
<... other widgets go here ...>
```
Because this is a TUI app that does not return anything when closed, the `"cmd:clearonstart"` option doesn't change the behavior, so it has been excluded.
# Web Widgets
Sometimes, it is desireable to open a page directly to a website. That can easily be accomplished by creating a custom `"web"` widget. They have the following form in general:
```json
{
<... other widgets go here ...>,
"<widget name>": {
"icon": "<fontawesome icon name>",
"label": "<the text label of the widget>",
"color": "<the color of the label>",
"blockdef": {
"meta": {
"view": "web",
"url": "<url of the first webpage>"
}
}
},
<... other widgets go here ...>
}
```
The `WidgetConfigType` takes the usual options common to all widgets. The `MetaTSType` can include the keys listed below:
| Key | Description |
|-----|-------------|
| "view" | A string that specifies the general type of widget. In the case of custom web widgets, this must be set to `"web"`.|
| "url" | This string is the url of the current page. As part of a widget, it will serve as the page the widget starts at. If not specified, this will default to the globally configurable `"web:defaulturl"` which is [https://github.com/wavetermdev/waveterm](https://github.com/wavetermdev/waveterm) on a fresh install. |
| "pinnedurl" | (optional) This string is the url the homepage button will take you to. If not specified, this will default to the globally configurable `"web:defaulturl"` which is [https://github.com/wavetermdev/waveterm](https://github.com/wavetermdev/waveterm) on a fresh install. |
## Example Web Widgets
Say you want a widget that automatically starts at YouTube and will use YouTube as the home page. This can be done using:
```json
<... other widgets go here ...>,
"youtube" : {
"icon": "brands@youtube",
"label": "youtube",
"blockdef": {
"meta": {
"view": "web",
"url": "https://youtube.com",
"pinnedurl": "https://youtube.com"
}
}
},
<... other widgets go here ...>
```
Alternatively, say you want a web widget that opens to github as if it were a bookmark, but will use google as its home page after that. This can easily be done with:
```json
<... other widgets go here ...>,
"github" : {
"icon": "brands@github",
"label": "github",
"blockdef": {
"meta": {
"view": "web",
"url": "https://github.com",
"pinnedurl": "https://google.com"
}
}
},
<... other widgets go here ...>
```
# Sysinfo Widgets
The Sysinfo Widget is intentionally kept to a very small subset of possible values that we will expand over time. But it is still possible to configure your own version of it&mdash;for instance, if you want to load a different plot by default. The general form of this widget is:
```json
<... other widgets go here ...>,
"youtube" : {
"icon": "brands@youtube",
"label": "youtube",
"blockdef": {
"meta": {
"view": "sysinfo",
"graph:numpoints": <the max number of points in the graph>,
"sysinfo:type": <the name of the plot collection>,
}
}
},
<... other widgets go here ...>
```
The `WidgetConfigType` takes the usual options common to all widgets. The `MetaTSType` can include the keys listed below:
| Key | Description |
|-----|-------------|
| "view" | A string that specifies the general type of widget. In the case of custom sysinfo widgets, this must be set to `"sysinfo"`.|
| "graph:numpoints" | The maximum amount of points that can be shown on the graph. Equivalently, the number of seconds the graph window covers. This defaults to 100.|
| "sysinfo:type" | A string representing the collection of types to show on the graph. Valid values for this are `"CPU"`, `"Mem"`, `"CPU + Mem"`, and `All CPU`. Note that these are case sensitive. If no value is provided, the plot will default to showing `"CPU"`.|
## Example Sysinfo Widgets
Suppose you have a build process that lasts 3 minutes and you'd like to be able to see the entire build on the sysinfo graph. Also, you would really like to view both the cpu and memory since both are impacted by this process. In that case, you can set up a widget as follows:
```json
<... other widgets go here ...>,
"3min-info" : {
"icon": "circle-3",
"label": "3mininfo",
"blockdef": {
"meta": {
"view": "sysinfo",
"graph:numpoints": 180,
"sysinfo:type": "CPU + Mem"
}
}
},
<... other widgets go here ...>
```
This will load show both the CPU and Memory plots by default while showing 180 seconds worth of data.
Now, suppose you are fine with the default 100 points (and 100 seconds) but would like to show all of the CPU data when launched. In that case, you can write:
```json
<... other widgets go here ...>,
"all-cpu" : {
"icon": "chart-scatter",
"label": "all-cpu",
"blockdef": {
"meta": {
"view": "sysinfo",
"sysinfo:type": "All CPU"
}
}
},
<... other widgets go here ...>
```

BIN
docs/static/img/widget-example.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB