goi3bar

package module
v0.0.0-...-b5efdfc Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2023 License: GPL-2.0 Imports: 10 Imported by: 28

README

goi3bar

GoDoc

Finally, a configurable, lightweight and easily extensible replacement for i3status.

Why use this over several other alternatives?

  • Speed. This performs better than its' cousins written in interpreted languages (python, php, etc)
  • Fine-grained concurrency. You can assign individual timings to all plugins, allowing you to make expensive calls less frequently (think making a network call to retrieve the weather, vs. updating the time).
  • Simple configuration. goi3bar is driven by JSON configuration, allowing you to easily customise your i3bar. Have you ever tried to use conky?
  • Simple Extensibility. Writing new plugins is much simpler than writing new functionality for a C-based project like conky. There are simple interfaces that let you build your own plugins, and handle JSON configuration. Look in the godoc for Producer, Genreator and Builder.

Talk is cheap! This powers my own i3bar:

i3bar1 i3bar2 i3bar3

Installation

If you have the pleasure of running Arch Linux, you can simply install the goi3bar-git package from the aur. Otherwise, read on:

  1. Install the go tool (at least version 1.5)
  2. Set up your GOPATH and PATH environment variables as described here.
  3. Download this repository and it's dependencies with go get github.com/denbeigh2000/goi3bar/...
  4. Install with go install github.com/denbeigh2000/goi3bar/cmd/goi3bar

Required for WLAN: iwconfig. Should be available in $PATH. Simple installation check:

$ which iwconfig>/dev/null && echo "yay" || echo "no"
yay

Usage

Run the goi3bar binary with your config file path as an argument:

$ goi3bar -config-path /path/to/your/config.json

Set this as the status_command field in ~/.i3/config.

If you see Error: status_command not found or is missing a library dependency (exit 127) in your i3bar, it means goi3bar is not in your $PATH. Either set your $PATH in the script that instantiates i3, such as xinitc, or provide the fully-qualified to the goi3bar binary, i.e. /home/denbeigh/dev/go/bin/goi3bar

Configuration

A configuration file is represented with JSON, consisting of refresh interval and zero or more entries

Each entry has a "package" referring to the plugin it uses, a "name" (anything, but must be unique) and an "options" struct, which will be dependent on the package you are using.

A set of packages come pre-included in the default "goi3bar" binary

Package key Function
cpu_load 1, 5, 15 minute CPU loads
cpu_util Current CPU percentage utilisation
memory Current memory usage
disk_usage Current free disk space
disk_access Current data I/O rate
battery Current battery level/remaining time
network Information about currently connected networks
clock Current time
Sample

This sample config defines an i3bar with custom colours, a 5 second refresh (not poll) interval, and a single memory printout with colour thresholds which refreshes every 10 seconds. A full sample config file with all options configured can be found in cmd/goi3bar/config.json.

{
    "colors": {
        "color_crit": "#FF0000",
        "color_warn": "#FFA500",
        "color_ok": "#00FF00",
        "color_general": "#FFFFFF"
    },
    "interval": "5s",
    "entries": [
        {
            "package": "memory",
            "name": "memory",
            "options": {
                "interval": "10s",
                "warn_threshold": 75,
                "crit_threshold": 85
            }
        }
    ]

TODO

Currently have:

  • Support (but no action) for click events
  • Configuration via JSON
  • Formattable clock
  • Memory usage (with configurable color thresholds)
  • CPU load averages (with configurable color thresholds)
  • Battery values (with automagic discovery and configurable thresholds)
  • Network info with funky applet which only shows most preferred connected network
  • Disk read/write rates
  • Disk usage

Want to have:

  • Unit testing!
  • More configurability for memory, battery moinitors (e.g., formattable)
  • Support for more batteries(?) This was written for a ThinkPad x240 because that's what I have. Pull requests welcome if some battery functionality does not work on your machine.

Documentation

Overview

Package goi3bar is a package that is capable of generating output suitable for i3bar. i3bar output is created by outputting JSON, which is defined in the i3bar documentation, found at http://i3wm.org/docs/i3bar-protocol.html

How to put data on the bar

A single i3bar output struct is represented as an Output. Any applet wanting to display information on the bar must create output of type []Output. The two interfaces that produce []Output are Producer and Generator.

Registering new plugins

To register a new plugins on the bar, prodvide a unique key and Producer to I3bar.Register. Remember to specify an order of applets before starting the bar. This can be done by providing all keys in the desired order as a slice to the I3bar.Order function.

Producer and Generator

The Producer is the interface that must be implemented when registering a plugin with an I3bar. It has one method, Produce(), which returns a channel of []Output. Whenever the I3bar produces new output, it will use the most recently received []Output it received from that Producer.

It is recommended that you implement this interface only if you have a need to manage your own output scheduling - if you can generate output in a non-blocking way, implement the Generator method instead.

Examples of required implementation of the Producer interface can be found in the disk IO or CPU percentage plugins.

If you do not need to manage your own scheduling, you should implement the Generator interface instead. It has one method, Generate(), that is assumed to be non-blocking and will be called at regular intervals. To register a generator with an I3bar, wrap it in a BaseProducer, which will return a Producer with managed scheduling.

Examples of the Generator+BaseProducer plugins are the clock, battery, disk usage and network packages

Clicker

The Clicker is the interface that must be implemented to support interaction through click events. To properly support this, you must also emit a Name value in your Output structs, which must match the name your Producer was registered with, otherwise the event will be unable to be routed back to your Producer.

Builder

The Builder is the interface that must be implemented when making your plugin available to the user through the configuration file interface. Look in the config package docs for detailed info on how to provide an API through the config file.

Index

Constants

View Source
const (
	DefaultColorGeneral = "#FFFFFF"
	DefaultColorOK      = "#00FF00"
	DefaultColorWarn    = "#FFA500"
	DefaultColorCrit    = "#FF0000"
)

These colors are the default colors used for alert state if none are given.

Variables

View Source
var ColorRegexp = regexp.MustCompile("#[0-9A-Fa-f]{6}")
View Source
var DefaultColors = Colors{
	General: DefaultColorGeneral,
	OK:      DefaultColorOK,
	Warn:    DefaultColorWarn,
	Crit:    DefaultColorCrit,
}

These are colors that should be used through the program. They will respect custom configuration given by the user in their JSON config.

Functions

func IsColorValid

func IsColorValid(c string) (err error)

func ParseColor

func ParseColor(c string) (string, error)

Types

type BaseProducer

type BaseProducer struct {
	Generator

	Interval time.Duration
	Name     string
}

A BaseProducer is a simple Producer, which generates output at regular intervals using a Generator.

func (*BaseProducer) Produce

func (p *BaseProducer) Produce(kill <-chan struct{}) <-chan []Output

Produce implements Producer. It creates a new value from the Generator every interval, and sends it down the provided channel

type BaseProducerClicker

type BaseProducerClicker struct {
	GeneratorClicker

	Interval time.Duration
	Name     string
}

A BaseProducerClicker is like a BaseProducer, but it uses a GeneratorClicker instead of a Generator so it can also implement Clicker

func (*BaseProducerClicker) Produce

func (p *BaseProducerClicker) Produce(kill <-chan struct{}) <-chan []Output

type ClickEvent

type ClickEvent struct {
	Name     string `json:"name"`
	Instance string `json:"instance"`
	Button   int    `json:"button"`
	XCoord   int    `json:"x"`
	YCoord   int    `json:"y"`
}

type Clicker

type Clicker interface {
	Click(ClickEvent) error
}

A Clicker receives click events from the i3bar. If a registered Producer also implements Clicker, then that its' Click method will be called with the click event received from i3bar.

type Colors

type Colors struct {
	General string `json:"color_general"`
	OK      string `json:"color_ok"`
	Warn    string `json:"color_warn"`
	Crit    string `json:"color_crit"`
}

func (*Colors) Update

func (c *Colors) Update(other Colors) error

type Generator

type Generator interface {
	Generate() ([]Output, error)
}

A Generator generates content to put on an i3bar. Other functions will call Generate to create output for the i3bar. A Generator should define how, not when the output is built.

func NewOrderedMultiGenerator

func NewOrderedMultiGenerator(g map[string]Generator, order []string) Generator

NewOrderedMultiGenerator creates a new OrderedMultiGenerator. It takes a map of key -> generator pairs, as well as a slice of keys specifying the order the items should appear on the bar.

type GeneratorClicker

type GeneratorClicker interface {
	Generator
	Clicker
}

A GeneratorClicker is both a Generator and a Clicker. It exists so we can have a concrete implementation built on BaseProducer that can also be used for plugins that implement Clicker

type I3bar

type I3bar struct {
	// contains filtered or unexported fields
}

I3bar is the data structure that represents a single i3bar.

func NewI3bar

func NewI3bar(update time.Duration) *I3bar

NewI3bar returns a new *I3bar. The update duration determines how often data will be sent to i3bar through stdout

func (I3bar) Kill

func (i I3bar) Kill()

Kill kills the i3bar (and all resgistered Producers)

func (*I3bar) Order

func (i *I3bar) Order(keys []string) error

Order determines the order in which items appear on the i3bar. The given slice must have each registered key appearing in it exactly once.

func (*I3bar) Register

func (i *I3bar) Register(key string, p Producer)

Register registers a new Producer with the I3bar. The I3bar expects incoming Update packets to be associated with a key registered with this function

func (*I3bar) Start

func (i *I3bar) Start(clicks io.Reader)

Start starts the i3bar (and all registered Producers)

type InvalidColorErr

type InvalidColorErr string

func (InvalidColorErr) Error

func (i InvalidColorErr) Error() string

type MultiGenerator

type MultiGenerator struct {
	// contains filtered or unexported fields
}

MultiGenerator is a Generator that combines the output of multiple Generators. Consistent order is not guaranteed across multiple generations

func NewMultiGenerator

func NewMultiGenerator(g []Generator) MultiGenerator

NewMultiGenerator takes a slice of generators and returns a single Generator

func (MultiGenerator) Generate

func (m MultiGenerator) Generate() ([]Output, error)

Generate implements Generator

type MultiProducer

type MultiProducer struct {
	// contains filtered or unexported fields
}

MultiProducer is a simple Producer that groups multiple Producers.

func NewMultiProducer

func NewMultiProducer(m map[string]Producer) MultiProducer

NewMultiProducer creates a new MultiProducer

func (MultiProducer) MultiRegister

func (m MultiProducer) MultiRegister(r registerer)

MultiRegister takes a registerer and uses it to register all of its' Producers

func (MultiProducer) Produce

func (m MultiProducer) Produce(kill <-chan struct{}) <-chan []Output

Produce implements Producer

type OrderedMultiGenerator

type OrderedMultiGenerator struct {
	// contains filtered or unexported fields
}

OrderedMultiGenerator is a Generator that can generate output for multiple Generators, and keeps the order of outputs the same.

func (*OrderedMultiGenerator) Generate

func (g *OrderedMultiGenerator) Generate() ([]Output, error)

Generate implements Generator

type Output

type Output struct {
	Align     string `json:"align,omitempty"`
	Color     string `json:"color,omitempty"`
	FullText  string `json:"full_text"`
	Instance  string `json:"instance,omitempty"`
	MinWidth  string `json:"min_width,omitempty"`
	Name      string `json:"name,omitempty"`
	ShortText string `json:"short_text,omitempty"`
	Separator bool   `json:"separator"`
	Urgent    bool   `json:"urgent"`
}

Output represends a single item on the i3bar.

type Producer

type Producer interface {
	Produce(kill <-chan struct{}) <-chan []Output
}

A Producer pushes content updates to the i3bar. It is responsible for managing how often an item delivers its updates to the i3bar. These updates are usually generated using a Generator.

type ProducerClicker

type ProducerClicker interface {
	Producer
	Clicker
}

A ProducerClicker is both a Producer and a Clicker. It exists so we can have a concrete implementation built on BaseProducer that can also be used for plugins that implement Clicker

type StaticGenerator

type StaticGenerator []Output

A StaticGenerator is a simple Generator that returns the same Output each time.

func (StaticGenerator) Generate

func (g StaticGenerator) Generate() ([]Output, error)

Generate implements Generator

type Update

type Update struct {
	Key string
	Out []Output
}

Update is a packet, received from a Producer, that updates the current Outputs matching the given Key. The Key should correspond to a registered Producer.

Directories

Path Synopsis
cmd
The config package contains the API needed to make your plugin configurable.
The config package contains the API needed to make your plugin configurable.
packages
cpu

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL