Merge wiki

This commit is contained in:
luke bonham 2014-01-21 16:01:44 +01:00
commit 6cc550655f
22 changed files with 1305 additions and 0 deletions

34
Home.md Normal file
View File

@ -0,0 +1,34 @@
Welcome to the Lain wiki!
Dependencies
------------------
Package | Requested by | Reason of choice
--- | --- | ---
alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | /
curl | widgets accessing network resources | LuaSocket is not a core library, and still not available for Lua 5.2+. LuaSSL is out of date.
imagemagick | album arts in [mpd](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering.
Installation
---------------
### Arch Linux
[AUR package](https://aur.archlinux.org/packages/lain/)
### Other distributions
git clone https://github.com/copycat-killer/lain.git ~/.config/awesome/lain
Usage
--------
First, include it into your `rc.lua`:
local lain = require("lain")
Then check out the submodules you want:
- [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts)
- [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
- [Utilities](https://github.com/copycat-killer/lain/wiki/Utilities)

298
Layouts.md Normal file
View File

@ -0,0 +1,298 @@
Currently, there are **8** layouts.
lain/layout
.
|-- termfair
|-- centerfair
|-- cascade
|-- cascadetile
|-- centerwork
|-- uselessfair
|-- uselesspiral
`-- uselesstile
Just add your favourites to ``layouts`` table:
layouts =
{
...
lain.layout.termfair,
lain.layout.uselesstile,
...
}
Or set them on specific tags like this:
awful.layout.set(lain.layout.uselessfair, tags[1][7])
How do layouts work?
=========================
termfair
--------
I do a lot of work on terminals. The common tiling algorithms usually
maximize windows, so you'll end up with a terminal that has about 200
columns or more. That's way too much. Have you ever read a manpage in a
terminal of this size?
This layout restricts the size of each window. Each window will have the
same width but is variable in height. Furthermore, windows are
left-aligned. The basic workflow is as follows (the number above the
screen is the number of open windows, the number in a cell is the fixed
number of a client):
(1) (2) (3)
+---+---+---+ +---+---+---+ +---+---+---+
| | | | | | | | | | | |
| 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | ->
| | | | | | | | | | | |
+---+---+---+ +---+---+---+ +---+---+---+
(4) (5) (6)
+---+---+---+ +---+---+---+ +---+---+---+
| 4 | | | | 5 | 4 | | | 6 | 5 | 4 |
+---+---+---+ -> +---+---+---+ -> +---+---+---+
| 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 |
+---+---+---+ +---+---+---+ +---+---+---+
The first client will be located in the left column. When opening
another window, this new window will be placed in the left column while
moving the first window into the middle column. Once a row is full,
another row above it will be created.
Default number of columns and rows are respectively taken from `nmaster`
and `ncol` values in `awful.tag`, but you can set your own.
For example, this sets `termfair` to 3 columns and at least 1 row:
lain.layout.termfair.nmaster = 3
lain.layout.termfair.ncol = 1
centerfair
----------
Similar to `termfair`, but with fixed number of vertical columns. Cols are centerded until there are `nmaster` columns, then windows are stacked as slaves, with possibly `ncol` clients per column at most.
(1) (2) (3)
+---+---+---+ +-+---+---+-+ +---+---+---+
| | | | | | | | | | | | |
| | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | ->
| | | | | | | | | | | | |
+---+---+---+ +-+---+---+-+ +---+---+---+
(4) (5)
+---+---+---+ +---+---+---+
| | | 3 | | | 2 | 4 |
+ 1 + 2 +---+ -> + 1 +---+---+
| | | 4 | | | 3 | 5 |
+---+---+---+ +---+---+---+
Like `termfair`, default number of columns and rows are respectively taken from `nmaster`
and `ncol` values in `awful.tag`, but you can set your own.
For example:
lain.layout.centerfair.nmaster = 3
lain.layout.centerfair.ncol = 1
cascade
-------
Cascade all windows of a tag.
You can control the offsets by setting these two variables:
lain.layout.cascade.cascade_offset_x = 64
lain.layout.cascade.cascade_offset_y = 16
The following reserves space for 5 windows:
lain.layout.cascade.nmaster = 5
That is, no window will get resized upon the creation of a new window,
unless there's more than 5 windows.
cascadetile
-----------
Similar to `awful.layout.suit.tile` layout, however, clients in the slave
column are cascaded instead of tiled.
Left column size can be set, otherwise is controlled by `mwfact` of the
tag. Additional windows will be opened in another column on the right.
New windows are placed above old windows.
Whether the slave column is placed on top of the master window or not is
controlled by the value of `ncol`. A value of 1 means "overlapping slave column"
and anything else means "don't overlap windows".
Usage example:
lain.layout.cascadetile.cascade_offset_x = 2
lain.layout.cascadetile.cascade_offset_y = 32
lain.layout.cascadetile.extra_padding = 5
lain.layout.cascadetile.nmaster = 5
lain.layout.ncol = 1
`extra_padding` reduces the size of the master window if "overlapping
slave column" is activated. This allows you to see if there are any
windows in your slave column.
Setting `cascade_offset_x` to a very small value or even 0 is reccommended to avoid wasting space.
centerwork
----------
You start with one window, centered horizontally:
+--------------------------+
| +----------+ |
| | | |
| | | |
| | | |
| | MAIN | |
| | | |
| | | |
| | | |
| | | |
| +----------+ |
+--------------------------+
This is your main working window. You do most of the work right here.
Sometimes, you may want to open up additional windows. They're put in
the following four slots:
+--------------------------+
| +---+ +----------+ +---+ |
| | | | | | | |
| | 0 | | | | 1 | |
| | | | | | | |
| +---+ | MAIN | +---+ |
| +---+ | | +---+ |
| | | | | | | |
| | 2 | | | | 3 | |
| | | | | | | |
| +---+ +----------+ +---+ |
+--------------------------+
Yes, the number "four" is fixed. In total, you can only have five open
windows with this layout. Additional windows are not managed and set to
floating mode. **This is intentional**.
You can set the order of the four auxiliary windows. This is the default
configuration:
lain.layout.centerwork.top_left = 0
lain.layout.centerwork.top_right = 1
lain.layout.centerwork.bottom_left = 2
lain.layout.centerwork.bottom_right = 3
This means: The bottom left slot will be occupied by the third window
(not counting the main window). Suppose you want your windows to appear
in this order:
+--------------------------+
| +---+ +----------+ +---+ |
| | | | | | | |
| | 3 | | | | 0 | |
| | | | | | | |
| +---+ | MAIN | +---+ |
| +---+ | | +---+ |
| | | | | | | |
| | 2 | | | | 1 | |
| | | | | | | |
| +---+ +----------+ +---+ |
+--------------------------+
This would require you to use these settings:
lain.layout.centerwork.top_left = 3
lain.layout.centerwork.top_right = 0
lain.layout.centerwork.bottom_left = 2
lain.layout.centerwork.bottom_right = 1
*Please note:* If you use Awesome's default configuration, navigation in
this layout may be very confusing. How do you get from the main window
to satellite ones depends on the order in which the windows are opened.
Thus, use of `awful.client.focus.bydirection()` is suggested.
Here's an example:
globalkeys = awful.util.table.join(
...
awful.key({ modkey }, "j",
function()
awful.client.focus.bydirection("down")
if client.focus then client.focus:raise() end
end),
awful.key({ modkey }, "k",
function()
awful.client.focus.bydirection("up")
if client.focus then client.focus:raise() end
end),
awful.key({ modkey }, "h",
function()
awful.client.focus.bydirection("left")
if client.focus then client.focus:raise() end
end),
awful.key({ modkey }, "l",
function()
awful.client.focus.bydirection("right")
if client.focus then client.focus:raise() end
end),
...
)
uselessfair, uselesspiral & uselesstile
---------------------------------------
These are duplicates of the stock `fair`, `spiral` and `tile` layouts.
However, "useless gaps" (see below) have been added.
Useless gaps
============
Useless gaps are gaps between windows. They are "useless" because they
serve no special purpose despite increasing overview. I find it easier
to recognize window boundaries if windows are set apart a little bit.
The `uselessfair` layout, for example, looks like this:
+================+
# #
# +---+ +---+ #
# | 1 | | | #
# +---+ | | #
# | 3 | #
# +---+ | | #
# | 2 | | | #
# +---+ +---+ #
# #
+================+
All of lain layouts provide useless gaps. To set the width of the gaps,
you have to add an item called `useless_gap_width` in your `theme.lua`.
If it doesn't exist, the width will default to 0.
Example:
theme.useless_gap_width = 10
What about layout icons?
========================
They are located in ``lain/icons/layout``.
To use them, add lines to your ``theme.lua`` like this:
theme.lain_icons = os.getenv("HOME") .. "/.config/awesome/lain/icons/layout/default/"
theme.layout_termfair = theme.lain_icons .. "termfairw.png"
theme.layout_cascade = theme.lain_icons .. "cascadew.png"
theme.layout_cascadetile = theme.lain_icons .. "cascadetilew.png"
theme.layout_centerwork = theme.lain_icons .. "centerworkw.png"
Credits goes to [Nicolas Estibals](https://github.com/nestibal) for creating
layout icons for default theme.
You can use them as a template for your custom versions.
[<- home](https://github.com/copycat-killer/lain/wiki)

163
Utilities.md Normal file
View File

@ -0,0 +1,163 @@
markup
------
Made markup easier!
First, require it like this:
local markup = lain.util.markup
then you can call its functions:
+-- markup
|
|`-- bold() Set bold.
|`-- italic() Set italicized text.
|`-- strike() Set strikethrough text.
|`-- underline() Set underlined text.
|`-- monospace() Set monospaced text.
|`-- big() Set bigger text.
|`-- small() Set smaller text.
|`-- font() Set the font of the text.
|
|`--+ bg
| |
| |`-- color() Set background color.
| |`-- focus() Set focus background color.
| |`-- normal() Set normal background color.
| `-- urgent() Set urgent background color.
|
|`--+ fg
| |
| |`-- color() Set foreground color.
| |`-- focus() Set focus foreground color.
| |`-- normal() Set normal foreground color.
| `-- urgent() Set urgent foreground color.
|
|`-- focus() Set both foreground and background focus colors.
|`-- normal() Set both foreground and background normal colors.
`-- urgent() Set both foreground and background urgent colors.
they all take one argument, which is the text to markup, except `fg.color` and `bg.color`:
markup.fg.color(text, color)
markup.bg.color(text, color)
dynamic tagging
---------------
That is:
- add a new tag;
- rename current tag;
- move current tag;
- remove current tag.
If you delete a tag, any rule set on it shall be broken, so be careful.
Use it with key bindings like these:
awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag(mypromptbox) end),
awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end),
awful.key({ modkey, "Shift" }, "Left", function () lain.util.move_tag(1) end), -- move to next tag
awful.key({ modkey, "Shift" }, "Right", function () lain.util.move_tag(-1) end), -- move to previous tag
awful.key({ modkey, "Shift" }, "d", function () lain.util.remove_tag() end),
**Note** that these function won't work properly with [Copland theme](https://github.com/copycat-killer/awesome-copycats) or any other configuration that already uses a dynamic tagging module like [Eminent](https://github.com/copycat-killer/awesome-copycats/tree/master/eminent).
useless\_gaps\_resize
---------------------
Changes `beautiful.useless_gaps_width` on the fly.
The function takes an integer argument, being the amount of pixel to add/remove to gaps.
You could use it with these keybindings:
-- On the fly useless gaps change
awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end),
awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end),
where `altkey=Mod1`, or you could use it like this:
mywidget:buttons(awful.util.table.join (
awful.button({}, 4, function() lain.util.useless_gaps_resize(-1) end),
awful.button({}, 5, function() lain.util.useless_gaps_resize(1) end)
end)
))
so when hovering the mouse over `mywidget`, you can adjust useless gaps size by scrolling with the mouse wheel.
tag\_view\_nonempty
-------------------
This function lets you jump to the next/previous non-empty tag.
It takes two arguments:
* `direction`: `1` for next non-empty tag, `-1` for previous.
* `sc`: Screen which the taglist is in. Default is `mouse.screen` or `1`. This
argument is optional.
You can use it with key bindings like these:
-- Non-empty tag browsing
awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end),
awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end),
where `altkey = "Mod1"`.
menu\_clients\_current\_tags
----------------------------
Similar to `awful.menu.clients`, but this menu only shows the clients
of currently visible tags. Use it with a key binding like this:
awful.key({ "Mod1" }, "Tab",
function()
awful.menu.menu_keys.down = { "Down", "Alt_L", "Tab", "j" }
awful.menu.menu_keys.up = { "Up", "k" }
lain.util.menu_clients_current_tags({ width = 350 }, { keygrabber = true })
end),
magnify\_client
---------------
Set a client to floating and resize it in the same way the "magnifier"
layout does it. Place it on the "current" screen (derived from the mouse
position). This allows you to magnify any client you wish, regardless of
the currently used layout. Use it with a client keybinding like this:
clientkeys = awful.util.table.join(
...
awful.key({ modkey, "Control" }, "m", lain.util.magnify_client),
...
)
If you want to "de-magnify" it, just retype the keybinding.
niceborder\_{focus, unfocus}
----------------------------
By default, your `rc.lua` contains something like this:
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
You can change it to this:
client.connect_signal("focus", lain.util.niceborder_focus(c))
client.connect_signal("unfocus", lain.util.niceborder_unfocus(c))
Now, when a client is focused or unfocused, Awesome will look up its
nice value in `/proc/<pid>/stat`. If it's less than 0, the client is
classified as "high priority"; if it's greater than 0, the client is
classified as "low priority". If it's equal to 0, nothing special
happens.
This requires to define additional colors in your `theme.lua`. For example:
theme.border_focus_highprio = "#FF0000"
theme.border_normal_highprio = "#A03333"
theme.border_focus_lowprio = "#3333FF"
theme.border_normal_lowprio = "#333366"

53
Widgets.md Normal file
View File

@ -0,0 +1,53 @@
General usage
-------------
Every widget is output by a `function`.
For some widgets, `function` returns a `wibox.widget.textbox`, for others a table to be used for notification and update purposes.
Every widget may take either a table or a list of variables as argument.
If it takes a table, you have to define a function variable called `settings` in it, in order to make your customizations.
To markup the textbox, call `widget:set_markup(...)` within `settings`.
You can feed `set_markup` with predefined arguments, see the sections for all the details.
`widget` is a textbox, so you can threat it like any other `wibox.widget.textbox`.
Here follows an example:
mycpu = lain.widgets.cpu({
timeout = 4,
settings = function()
widget:set_markup("Cpu " .. cpu_now.usage)
end
})
If you want to see more complex applications, check [awesome-copycats](https://github.com/copycat-killer/awesome-copycats).
Index
-----
- [alsa](https://github.com/copycat-killer/lain/wiki/alsa)
- [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar)
- [bat](https://github.com/copycat-killer/lain/wiki/bat)
- [borderbox](https://github.com/copycat-killer/lain/wiki/borderbox)
- [calendar](https://github.com/copycat-killer/lain/wiki/calendar)
- [cpu](https://github.com/copycat-killer/lain/wiki/cpu)
- [fs](https://github.com/copycat-killer/lain/wiki/fs)
- [imap](https://github.com/copycat-killer/lain/wiki/imap)
- [maildir](https://github.com/copycat-killer/lain/wiki/maildir)
- [mem](https://github.com/copycat-killer/lain/wiki/mem)
- [mpd](https://github.com/copycat-killer/lain/wiki/mpd)
- [net](https://github.com/copycat-killer/lain/wiki/net)
- [sysload](https://github.com/copycat-killer/lain/wiki/sysload)
- [temp](https://github.com/copycat-killer/lain/wiki/temp)
- [yawn](https://github.com/copycat-killer/lain/wiki/yawn)
Users contributed
----------------
- [task](https://github.com/copycat-killer/lain/wiki/task)
- [tpbat](https://github.com/copycat-killer/lain/wiki/tpbat)
- [brightness](https://github.com/copycat-killer/lain/wiki/brightness)

53
alsa.md Normal file
View File

@ -0,0 +1,53 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows and controls alsa volume with a textbox.
volumewidget = lain.widgets.alsa()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 5
`channel` | Mixer channel | string | "Master"
`settings` | User settings | function | empty function
`settings` can use the following variables:
Variable | Meaning | Type | Values
--- | --- | --- | ---
`volume_now.level` | Self explained | int | 0-100
`volume_now.status` | Device status | string | "on", "off"
### output table
Variable | Meaning | Type
--- | --- | ---
`widget` | The widget | `wibox.widget.textbox`
`update` | Update `widget` | function
You can control the widget with key bindings like these:
-- Volume control
awful.key({ altkey }, "Up",
function ()
awful.util.spawn("amixer set Master 1%+")
volumewidget.update()
end),
awful.key({ altkey }, "Down",
function ()
awful.util.spawn("amixer set Master 1%-")
volumewidget.update()
end),
awful.key({ altkey }, "m",
function ()
awful.util.spawn("amixer set Master playback toggle")
volumewidget.update()
end),
awful.key({ altkey, "Control" }, "m",
function ()
awful.util.spawn("amixer set Master playback 100%", false )
volumewidget.update()
end),
where `altkey = "Mod1"`.

85
alsabar.md Normal file
View File

@ -0,0 +1,85 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows and controls alsa volume with a progressbar; provides tooltips, notifications, and color changes at mute/unmute switch.
volume = lain.widgets.alsabar()
* Left click: Launch `alsamixer` in your `terminal`.
* Right click: Mute/unmute.
* Scroll wheel: Increase/decrase volume.
The function takes a table as optional argument, which can contain:
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 4
`settings` | User settings | function | empty function
`width` | Bar width | int | 63
`height` | Bar height | int | 1
`ticks` | Set bar ticks on | boolean | false
`ticks_size` | Ticks size | int | 7
`vertical` | Set the bar vertical | boolean | false
`channel` | Mixer channel | string | "Master"
`step` | Step at which volume is increased/decreased | string | "5%"
`colors` | Bar colors | table | see **colors**
`notifications` | Notifications settings | table | see **notifications**
### colors
Variable | Meaning | Type | Default
--- | --- | --- | ---
`background` | Bar backgrund color | string | `beautiful.bg_normal`
`mute` | Bar mute color | string | "#EB8F8F"
`unmute` | Bar unmute color | string | "#A4CE8A"
### notifications
Variable | Meaning | Type | Default
--- | --- | --- | ---
`font` | Notifications font | string | The one defined in `beautiful.font`
`font_size` | Notifications font size | string | "11"
`color` | Notifications color | string | `beautiful.fg_normal`
`bar_size` | Wibox height | int | 18
It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height.
`settings` can use the following variables:
Variable | Meaning | Type | Values
--- | --- | --- | ---
`volume_now.level` | Self explained | int | 0-100
`volume_now.status` | Device status | string | "on", "off"
### output table
Variable | Meaning | Type
--- | --- | ---
`bar` | The widget | `awful.widget.progressbar`
`channel` | Alsa channel | string
`step` | Increase/decrease step | string
`notify` | The notification | function
You can control the widget with key bindings like these:
-- ALSA volume control
awful.key({ altkey }, "Up",
function ()
awful.util.spawn("amixer -q set " .. volume.channel .. " " .. volume.step .. "+")
volume.notify()
end),
awful.key({ altkey }, "Down",
function ()
awful.util.spawn("amixer -q set " .. volume.channel .. " " .. volume.step .. "-")
volume.notify()
end),
awful.key({ altkey }, "m",
function ()
awful.util.spawn("amixer -q set " .. volume.channel .. " playback toggle")
volume.notify()
end),
awful.key({ altkey, "Control" }, "m",
function ()
awful.util.spawn("amixer -q set " .. volume.channel .. " playback 100%")
volume.notify()
end),
where `altkey = "Mod1"`.

30
bat.md Normal file
View File

@ -0,0 +1,30 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows in a textbox the remaining time and percentage capacity of your laptop battery, as well as
the current wattage.
Displays a notification when battery is low or critical.
mybattery = lain.widgets.bat()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 30
`battery` | Identifier of the battery | string | "BAT0"
`notify` | Enable notifications | string | "on"
`settings` | User settings | function | empty function
`settings` can use the `bat_now` table, which contains the following strings:
- `status` ("Not present", "Charging", "Discharging");
- `perc`;
- `time`;
- `watt`.
To disable warning notifications, set `notify` to `"off"`.
### output
A textbox.

49
borderbox.md Normal file
View File

@ -0,0 +1,49 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Creates a thin wibox at a position relative to another wibox.
This allows to create "borders" for your wiboxes.
lain.widget.borderbox(relbox, s, args)
`relbox` and `s` (an integer being screen number) are required arguments, `args` is an optional table
which can contain:
Variable | Meaning | Type | Default
--- | --- | --- | ---
`position` | Position of the additional box | string | "above"
`color` | Color of the additional box | string | `#FFFFFF`
`size` | Size in pixels of the additional box | int | 1
Possible values for `.position`: `top`, `bottom`, `left` and `right`.
### Example usage
Think of this as a wibox:
[======================]
If `args.position = "above"`, then you'll get an additional wibox below
the existing one:
________________________
[======================]
It'll match position and size of the existing wibox.
If your main wiboxes are stored in a table called `mywibox` (one wibox
for each screen) and are located at the bottom of your screen, then this
adds a borderbox on top of them:
-- Layout section
for s = 1, screen.count() do
...
-- Most likely, you'll want to do this as well:
awful.screen.padding(screen[s], "bottom")
-- Create the box and place it above the existing box.
lain.widgets.borderbox(mywibox[s], s )
...
end

40
brightness.md Normal file
View File

@ -0,0 +1,40 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows the current level of screen brightness in a textbox.
brightnesswidget = lain.widgets.contrib.brightness()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 5
`backlight` | Backlight video | string | "acpi_video0"
`settings` | User settings | function | empty function
`settings` can use the following variables:
Variable | Meaning | Type | Values
--- | --- | --- | ---
`brightness_now` | Brightness level | int | 0-100
### output table
Variable | Meaning | Type
--- | --- | ---
`widget` | The widget | `wibox.widget.textbox`
`update` | Update `widget` | function
You can control the widget with key bindings like these:
-- Brightness control
awful.key({}, "XF86MonBrightnessUp",
function ()
awful.util.spawn("xbacklight -inc 1")
brightnesswidget.update()
end),
awful.key({}, "XF86MonBrightnessDown",
function ()
awful.util.spawn("xbacklight -dec 1")
brightnesswidget.update()
end),

31
calendar.md Normal file
View File

@ -0,0 +1,31 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Attaches a calendar notification to a widget.
lain.widgets.calendar:attach(widget, args)
- Left click: switch to previous month.
- Right click: switch to next month.
`args` is an optional table which can contain:
Variable | Meaning | Type | Default
--- | --- | --- | ---
`icons` | Path to calendar icons | string | [lain/icons/cal/white](https://github.com/copycat-killer/lain/tree/master/icons/cal/white)
`font_size` | Calendar font size | int | 12
`fg` | Calendar foreground color | string | `beautiful.fg_normal`
`bg` | Calendar background color | string | `beautiful.bg_normal`
`position` | Calendar position | string | "top_right"
`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify).
Notification will show an icon displaying current day, and formatted output
from ``cal`` with current day highlighted.
You can call the notification with a key binding like this:
awful.key({ altkey }, "c", function () lain.widgets.calendar:show(7) end),
where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds.
**Note that** this widget exploits ``cal`` to do the alignment, in order to avoid more dozens of code lines, but this requires that your system font is monospaced.

18
cpu.md Normal file
View File

@ -0,0 +1,18 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows in a textbox the average CPU usage percent for a given amount of time.
mycpuusage = lain.widgets.cpu()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 5
`settings` | User settings | function | empty function
`settings` can use the string `cpu_now.usage`, which is the cpu use percentage.
### output
A textbox.

45
fs.md Normal file
View File

@ -0,0 +1,45 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows disk space usage for a set partition.
Displays a notification when the partition is full or has low space.
mypartition = lain.widgets.fs()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds -| int | 600
`partition` | Partition to monitor | string | "/"
`settings` | User settings | function | empty function
`settings` can use the following `partition` related float values: `fs_now.used`, `fs_now.available`, `fs_now.size_mb`, `fs_now.size_gb`.
It can also use value strings in these formats:
fs_info[p .. "used_p"]
fs_info[p .. "avail_p"]
fs_info[p .. "size_mb"]
fs_info[p .. "size_gb"]
where `p` is the last column of `df` command ("/", "/home", "/boot", ...).
This means you can set the widget for a certain partition, but you can look up at others too.
Finally, `settings` can modify `fs_notification_preset` table too. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition:
fs_notification_preset = { fg = beautiful.fg_normal }
### output table
Variable | Meaning | Type
--- | --- | ---
`widget` | The widget | `wibox.widget.textbox`
`show` | The notification | function
You can display the notification with a key binding like this:
awful.key({ altkey }, "h", function () mypartition.show(7) end),
where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds.

68
imap.md Normal file
View File

@ -0,0 +1,68 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows mail count in a textbox fetching over IMAP.
myimapcheck = lain.widgets.imap(args)
New mails are notified like this:
+--------------------------------------------+
| +---+ |
| |\ /| donald@disney.org has 3 new messages |
| +---+ |
+--------------------------------------------+
The function takes a table as argument. Required table parameters are:
Variable | Meaning | Type
--- | --- | ---
`server` | Mail server | string
`mail` | User mail | string
`password` | User password | string
while the optional are:
Variable | Meaning | Type | Default
--- | --- | --- | ---
`port` | IMAP port | int | 993
`timeout` | Refresh timeout seconds | int | 60
`is_plain` | Define whether `password` is a plain password (true) or a function that retrieves it (false) | boolean | false
`settings` | User settings | function
Let's focus better on `is_plain`.
The reason why it's false by default is to discourage the habit of storing passwords in plain.
So you can set your password in plain like this:
myimapcheck = lain.widgets.imap({
is_plain = true,
password = "myplainpassword",
[...]
})
and you'll have the same security provided by `~/.netrc`.
**Or** you can use a keyring, like [python keyring](https://pypi.python.org/pypi/keyring):
myimapcheck = lain.widgets.imap({
password = "keyring get mymail",
[...]
})
When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want.
`settings` can use the value `mailcount`, an integer greater or equal to zero, and can modify `mail_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain.
Default definition:
mail_notification _preset = {
icon = lain/icons/mail.png,
position = "top_left"
}
Note that `mailcount` is 0 either if there are no new mails or credentials are invalid, so make sure you get the right settings.
### output
A textbox.

39
maildir.md Normal file
View File

@ -0,0 +1,39 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows maildirs status in a textbox.
Maildirs are structured as follows:
~/Mail
.
|-- arch
| |-- cur
| |-- new
| `-- tmp
|-- gmail
| |-- cur
| |-- new
| `-- tmp
.
.
.
therefore the widget checks whether there are files in the `new` directories.
If there's new mails, the textbox will say something like "mail: bugs(3), system(1)", otherwise it says
"no mail".
mymaildir = lain.widgets.maildir("/path/to/my/maildir")
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 60
`mailpath` | Path to your maildir | string | "~/Mail"
`settings` | User settings | function | empty function
`settings` can use the string `newmail`, which format will be something like defined above, or "no mail".
### output
A textbox.

18
mem.md Normal file
View File

@ -0,0 +1,18 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows memory status (in MiB) in a textbox.
mymem = lain.widgets.mem()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 3
`settings` | User settings | function | empty function
`settings` can use the strings `mem_now.used` (memory used MB) and `mem_now.swapused` (swap used MB).
### output
A textbox.

85
mpd.md Normal file
View File

@ -0,0 +1,85 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows MPD status in a textbox.
mpdwidget = lain.widgets.mpd()
Now playing songs are notified like this:
+--------------------------------------------------------+
| +-------+ |
| |/^\_/^\| Now playing |
| |\ O O /| Cannibal Corpse (Hammer Smashed Face) - 1993 |
| | '.o.' | Hammer Smashed Face (Radio Disney Version) |
| +-------+ |
+--------------------------------------------------------+
You need a file like this
(Front|front|Cover|cover|Art|art|Folder|folder)\.(jpg|jpeg|png|gif)
in the album folder in order to show album art too.
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 1
`password` | MPD password | string | ""
`host` | MPD server | string | "127.0.0.1"
`port` | MPD port | string | "6600"
`music_dir` | Music directory | string | "~/Music"
`cover_size` | Album art notification size | int | 100
`default_art` | Default art | string | ""
`settings` | User settings | function | empty function
`settings` can use `mpd_now` table, which contains the following string values:
- state (possible values: "play", "pause", "stop")
- file
- artist
- title
- album
- date
and can modify `mpd_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition:
mpd_notification_preset = {
title = "Now playing",
timeout = 6,
text = string.format("%s (%s) - %s\n%s", mpd_now.artist,
mpd_now.album, mpd_now.date, mpd_now.title)
}
### output table
Variable | Meaning | Type
--- | --- | ---
`widget` | The textbox | `wibox.widget.textbox`
`update` | The notification | function
You can control the widget with key bindings like these:
-- MPD control
awful.key({ altkey, "Control" }, "Up",
function ()
awful.util.spawn_with_shell("mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle")
mpdwidget.update()
end),
awful.key({ altkey, "Control" }, "Down",
function ()
awful.util.spawn_with_shell("mpc stop || ncmpcpp stop || ncmpc stop || pms stop")
mpdwidget.update()
end),
awful.key({ altkey, "Control" }, "Left",
function ()
awful.util.spawn_with_shell("mpc prev || ncmpcpp prev || ncmpc prev || pms prev")
mpdwidget.update()
end),
awful.key({ altkey, "Control" }, "Right",
function ()
awful.util.spawn_with_shell("mpc next || ncmpcpp next || ncmpc next || pms next")
mpdwidget.update()
end),
where `altkey = "Mod1"`.

26
net.md Normal file
View File

@ -0,0 +1,26 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Monitors network interfaces and shows current traffic in a textbox.
mynet = lain.widgets.net()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 2
`iface` | Network device | string | autodetected
`units` | Units | int | 1024 (kilobytes)
`settings` | User settings | function | empty function
Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), and so on.
`settings` can use the following `iface` related strings:
- `net_now.carrier` ("0", "1");
- `net_now.state` ("up", "down");
- `net_now.sent` and `net_now.received` (numbers).
### output
A textbox.

18
sysload.md Normal file
View File

@ -0,0 +1,18 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows the current system load.
mysysload = lain.widgets.sysload()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 5
`settings` | User settings | function | empty function
`settings` can use strings `load_1`, `load_5` and `load_15`, which are loadavg over 1, 5, and 15 minutes.
### output
A textbox.

30
task.md Normal file
View File

@ -0,0 +1,30 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Attaches a [taskwarrior](http://taskwarrior.org/projects/show/taskwarrior) notification to a widget, and lets to add/search tasks from the promptbox.
lain.widgets.contrib.task:attach(widget, args)
`args` is an optional table which can contain:
Variable | Meaning | Type | Default
--- | --- | --- | ---
`font_size` | Calendar font size | int | 12
`fg` | Calendar foreground color | string | `beautiful.fg_normal`
`bg` | Calendar background color | string | `beautiful.bg_normal`
`position` | Calendar position | string | "top_right"
`timeout` | Notification timeout seconds | int | 7
`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify).
Notification will show the output of `task` command.
You can call the notification with a key binding like this:
awful.key({ modkey, altkey }, "t", lain.widgets.contrib.task.show),
where ``altkey = "Mod1"``.
And you can prompt to add/search a task with key bindings like these:
awful.key({ modkey, }, "t", lain.widgets.contrib.task.prompt_add),
awful.key({ modkey, "Shift" }, "t", lain.widgets.contrib.task.prompt_search),

20
temp.md Normal file
View File

@ -0,0 +1,20 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
Shows the current core temperature in a textbox.
Reads from `/sys/class/thermal`, so value is expressed in Celsius.
mytemp = lain.widgets.temp()
### input table
Variable | Meaning | Type | Default
--- | --- | --- | ---
`timeout` | Refresh timeout seconds | int | 5
`settings` | User settings | function | empty function
`settings` can use the string `coretemp_now`, which means current core temperature, expressed in Celsius (linux standard).
### output
A textbox.

9
tpbat.md Normal file
View File

@ -0,0 +1,9 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi).
Includes hover notification with more details.
tpbatwidget = lain.widgets.contrib.tpbat()
Configuration is identical to [standard battery widget's](https://github.com/copycat-killer/lain/wiki/bat).

93
yawn.md Normal file
View File

@ -0,0 +1,93 @@
[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets)
(YAhoo! Weather Notification)
Yawn provides brief and compact Yahoo! Weather notification.
Usage
-----
You can ``register`` Yawn to get a set of widgets, or ``attach`` it to
an existent widget.
### register
yawn = lain.widgets.yawn(id, args)
- ``id``
An integer that defines the WOEID code of your city.
To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link.
It will look like:
http://weather.yahoo.com/united-states/california/san-diego-2487889/
and the last number in that link will be the ID you need.
- ``args``
A required table which can contain:
Variables | Meaning | Type | Possible values | Default value
--- | --- | --- | --- | ---
`u` | Units | string | "c" (Celsius), "f" (Fahrenheit) | "c"
`timeout` | Refresh timeout seconds | int | integers | 600
`settings` | User settings | function | function | empty function
`settings` can use strings `forecast`, `units`, and can modify `yawn_notification_preset` table, which
will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain.
The function `register` creates an imagebox icon and a textbox widget. Add them to you wibox like this:
right_layout:add(yawn.icon)
right_layout:add(yawn.widget)
Hovering over ``yawn.icon`` will display the notification.
### attach
lain.widgets.yawn.attach(widget, id, args)
Arguments:
- ``widget``
The widget which you want to attach Yawn to.
- ``id``
Same as in ``register``.
- ``args``
Same as in ``register``.
Hovering over ``widget`` will display the notification.
Popup shortcut
--------------
You can also create a keybinding for the weather popup like this:
awful.key( { "Mod1" }, "w", function () yawn.show(5) end )
where ``show`` argument is an integer defining timeout seconds.
Localization
------------
Default language is English, but Yawn can be localized.
Move to `localizations` subdirectory and fill `localization_template`.
Once you're done, rename it like your locale id. In my case:
$ lua
Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print(os.getenv("LANG"):match("(%S*$*)[.]"))
it_IT
>
hence I named my file "it_IT" (Italian localization).
**NOTE:** If you create a localization, feel free to send me! I will add it.