Zscroll
The most common use cases are described in this README. For complete information on every flag, please see the man page (or the help text for basic information on every flag).
Version 2.0 Breaking Changes
- Long options are now hyphenated (e.g.
--update-check
) - All boolean options take an argument (e.g.
--scroll false
) - Newlines will be used by default (
--newline
defaults to true) as zscroll’s primary use case is for panels, and this behavior is necessary for scrolling to work with polybar and lemonbar. -m
/-M
syntax has changed to eliminate the previous complicated rules- The
-f
and-c
flags have been removed. I don’t see them as having a legitimate use case (the default behavior for handling fullwidth characters is much saner), but if anyone would like them back, feel free to make an issue.-c
would count fullwidth characters as length 1, causing the scrolling text length to change.-f
would convert all letters to fullwidth if any fullwidth letters were found.
Simple Example
Scroll the currently playing mpd song:
$ zscroll -b "⮕ " "$(mpc current)"
# or
$ mpc current | zscroll -b "⮕ "
By default, zscroll will add ” - ” between the end and start of scrolling text. This can be adjusted with the -p
option. Here is a zoomed in example of the above command (with a 0.4 second update delay):
Installation
Arch
Install zscroll-git from the AUR.
Nix
Nix is a distro-independent package manager.
$ nix-env -i zscroll
Manual
$ git clone https://github.com/noctuid/zscroll
$ cd zscroll
$ sudo python3 setup.py install
This program will not work with Python 2. For this reason you must install with Python 3. This can be done in Ubuntu with sudo python3 setup.py install
and may be the same for other distributions. If this does not work for you, please consult your distribution’s documentation.
Note: asdf users might have to run asdf reshim
command before using zscroll
.
Dynamically Updating Text
Zscroll can now update its text by itself. This may be nice for panels that don’t allow for the user to conditionally start new processes. It also simplifies the logic necessary to change settings for the scrolling text and gets rid of the need for an ugly function to repeatedly kill and start the scroller.
A simple use case is where one might want to display the current window’s title. This can be done with the -u
option, which will run zscroll’s positional argument as a shell command to check for changes:
zscroll -b "| " -a " |" -u true "xtitle"
Zscroll even supports more complex updates by searching for a regular expression in the output of a command to determine whether certain settings should be changed. As an example, this can be useful for displaying a pause icon and prevent scrolling when the current song is paused. The following command will take these actions when “paused” is found in the output of the shell command mpc status
:
zscroll --before-text "♪ x" --delay 0.3 \
--match-command "mpc status" \
--match-text "playing" "--before-text 'î‚š '" \
--match-text "paused" "--before-text 'î‚› ' --scroll 0" \
--update-check true "mpc current"
# or shortopts
zscroll -b "♪ x" -d 0.3 \
-M "mpc status" \
-m "playing" "-b 'î‚š '" \
-m "paused" "-b 'î‚› ' -s 0" \
-u t "mpc current"
New options (and possibly new scroll-text) should be specified as the second argument to every -m
. Options not specified with an -m
will default to the user-specified values outside of the -m
(or the base defaults). Any option can be altered when a -m
search term is found (except for -m
and -M
, which will be ignored). Note that when multiple -m
options happen to be matched, it is the last one that will take effect.
See the man page for more information.
Fullwidth Characters
Zscroll intelligently deals with fullwidth characters by default by counting them as twice the length of halfwidth characters (and phasing them in and out in two steps). This ensures that the actual visual length and speed of the scrolling text does not change. Here is a normal-sized gif of the above command that demonstrates this:
Use with Polybar
Here’s an example of using zscroll instead of polybar’s mpd module.
In polybar config:
[module/mpd]
type = custom/script
exec = /path/to/script
tail = true
label-foreground = ${colors.music}
In the script:
#!/usr/bin/env bash
zscroll --before-text "♪ x" --delay 0.3 \
--match-command "mpc status" \
--match-text "playing" "--before-text 'î‚š '" \
--match-text "paused" "--before-text 'î‚› ' --scroll 0" \
--update-check true "mpc current" &
wait
For an alternate method that does not use zscroll’s dynamic updating, see here.
Similar
Why
I was using benghaem’s scroller for a while. I didn’t like that the arguments were all positional, the lack of a right text padding option, and the lack of an option to change the scroll speed. I found skroll afterwards which is nicer since it has options and an actual man page and is in the AUR. However, it doesn’t have a left text padding option which was necessary for my bar script to work properly. Also, they are both written in C, which doesn’t seem practical to me for such a simple script and is the main reason I created zscroll instead of contributing.
Zscroll supports the features I liked from each. It has a speed option, adds an option for right padding text, will work on text as an argument or piped into it, handles fullwidth characters intelligently, and has other advanced features.
I called this zscroll because it’s the last scroller I’ll use… but more importantly because I couldn’t think of another name.
Contributing
Zscroll is using black and isort for automatic formatting and import sorting. flake8 and pylint, and pydocstyle are used for linting. pytest is used for testing.
Development dependencies can be installed with make deps
or poetry installed
(poetry must be installed first). If you want to make a PR, please write tests for any added or fixed functionality and make sure that the code passes make lint
and make test
.
To automatically format with black when committing and abort the commit if there are any flake8 errors, you can install pre-commit and run pre-commit install
once in the repository root after cloning.