Update CHANGELOG to be sorted descending.
Move README Screenshot to above Installation.
Fix sporadic Display::Screen misdraws.

Sometimes after starting, not all parts of the screen were drawn
immediately. Fix by calling `Curses.refresh` within
`Display::Screen#initialize`, after panels are installed.
[#2] Redraw on terminal window resize (SIGWINCH).

Add `Display::Screen#term_height`,`#term_width` to report terminal lines
and columns instead of always using `Curses.lines`,`.cols`, since the
latter do not update after resize. Add `Display::Screen#missized?` to aid
detection of a window which is still resizing or missized otherwise.

Add `App#restart` for restarting an app, extending `#refresh_loop` to do
the actual restart.

Trap `SIGWINCH` calling `App#restart` in a similar way to `SIGINT`.
Wake up threads instead of REFRESH_SUBINTERVAL sleep increments.

Instead of sleeping in increments of `REFRESH_SUBINTERVAL` (so program
can exit in a reasonable amount of time), wake up sleeping threads on
quit, deprecating `REFRESH_SUBINTERVAL` entirely. Change `App#do_command`
to call `App#stop` instead of altering `@running` itself. After setting
`@running` status in `App#stop`, wake up any sleeping threads so they
can check whether they should be running.

This results in immediate exit on quit.

Also don't explicitly `require thread`, as this isn't necessary for Ruby
1.9 onwards.
[#3] Call #close properly when exception in Display::Screen#initialize .

When an exception occurred in `Display::Screen#initialize`, `#close` did
not get called, meaning Curses-related cleanup did not occur. Fix by
rescuing as part of `#initialize`, calling `#close`, and reraising.

This enables error messages to be output to the screen; otherwise,
nothing shows because of failure to shutdown Curses-related things.
[#3] Report executable errors friendily unless --debug .

If errors are raised within the application, rescue and report in a
friendly manner. An example of this is if the host cannot be reached.
Also return a non-zero exit status. Introduce `--debug` option, for
reraising so the stacktrace is reported.
[#3] Output errors to STDERR instead of STDOUT.

This is simlar to the `--debug` stacktrace behaviour, which is also
written to STDERR.
Refactor App, removing #refresh, #next_key, #missized? .

Remove `App` methods which were wrappers around `Display::Screen`
methods and only called once. Change ordering of methods.

HACK: Skip `App#refresh_loop` loop if no `@screen`; can't decide if
this only happens in certain test scenarios, or whether there is a valid
runtime scenario similar to that in `App#command_loop`.
[#5] Implement keyed switching between tabs, with skeleton Queues.

Extract threads wakeup to `App#wakey_wakey`, calling from `#stop` and
`#do_command`. This wakes threads for an immediate response, be it for
app shutdown or switching between tabs.

Define skeleton `Display::Panels::Queues`, with an empty structure.

Extend `App#do_command` to process `<w>` (Workers) and `<u>` (Queues).

Add tabs menu to `Display::Panels::Header`, with public `@panel_main`
for active vs inactive tab distinction.

Add `Display::Screen#panel_main=`, replacing `:workers` panel with
`:main`, and switching for Workers and Queues tabs.
[#5] Implement Spy::Queues, retrieving Sidekiq Stats Queues data.

This provides data equivalent to the `Sidekiq::Web` Queues page (but
not the linked Queue pages). It uses `Sidekiq::Stats#queues`, not
`Sidekiq::Queue`, as only the name and size of the queues are retrieved
(as per the `Sidekiq::Web` Queues page).

This is implemented in a similar way to `Spy::Workers`.
[#5] Define Display::Panels::Queues, equivalent to Queues page.

Adding to the existing skeleton, use the data provided by `Spy::Queues`
to display a list of active Sidekiq queues and their sizes. Note that it
is necessary to hook into `#refresh` and call `Spy::Queues#refresh`. The
list is defined to be precisely as many table rows long as the panel
minus the header row.

Note that the `Sidekiq::Web` Queue page (linked from Queues) is not
implemented as part of this work.
Merge branch 'panel-queues'
Fix Display::Subpanel#content length when data_l non-string.

`Display::Subpanel#content` worked when data_l `nil` as well as string.
When non-string, however, `.length` failed. For non-string data_r,
however, everything worked as expected, because of `.to_s` being called
implicitly. Fix by explicitly calling `.to_s`, which will also work for
`nil`.
[#6] Implement Spy::Retries, retrieving Sidekiq Retries data.

This provides data equivalent to the `Sidekiq::Web` Retries page (but
not the linked Retry pages). It uses `Sidekiq::RetrySet` with no limit.
Because of this, the current implementation could experience issues if
there are a large number of retries.

There is no sort applied to the list, so it should reflect any
underlying order returned from Sidekiq.

This is implemented in a similar way to `Spy::Workers`.
[#6] Define Display::Panels::Retries, equivalent to Retries page.

Using the data provided by `Spy::Retries`, define panel
`Display::Panels::Retries`. This displays a list of queued Sidekiq
retries. Note that it is necessary to hook into `#refresh` and call
`Spy::Retries#refresh`. The list is defined to be precisely as many
table rows long as the panel minus the header row.

Mount a retries panel in `Display::Screen` in the `:main` panel,
binding to keypress `<r>`. Add a Retries entry to the `:header` panel
menu.

Note that the `Sidekiq::Web` Retry page (linked from Retries) is not
implemented as part of this work.
Merge branch 'panel-retries'
Fix panel_main not restored after restart.

Expose panel_main as `Display::Screen#panel_main`, and use to restore
active tab after restart (triggered by resize) in `App#refresh_loop`.
[#7] Implement Spy::Schedules, retrieving Sidekiq Scheduled data.

This provides data equivalent to the `Sidekiq::Web` Scheduled page. It
uses `Sidekiq::ScheduledSet` with no limit. Because of this, the current
implementation could experience issues if there are a large number of
schedules.

There is no sort applied to the list, so it should reflect any
underlying order returned from Sidekiq.

The name 'Schedules' rather than 'Scheduled' is used for internal
consistency, despite it being named the latter in Sidekiq. I might live
to regret my choice.

This is implemented in a similar way to `Spy::Retries`.
[#7] Define Display::Panels::Schedules, equivalent to Scheduled page.

Using the data provided by `Spy::Schedules`, define panel
`Display::Panels::Schedules`. This displays a list of scheduled jobs.
Note that it is necessary to hook into `#refresh` and call
`Spy::Schedules#refresh`. The list is defined to be precisely as many
table rows long as the panel minus the header row.

Mount a schedules panel in `Display::Screen` in the `:main` panel,
binding to keypress `
`. Add a Schedules entry to the `:header` panel
menu, displayed as 'SCHEDULED' (to match `Sidekiq::Web`).