Getting Started
Running canto-curses
with no arguments will automatically start the daemon and connect to it. If you don’t have any settings, it will create some defaults for you.
You can use :help
or “?” to open help, which will list the built-in keybinds.
:help commands
will list the individual commands with a brief description of what they do.
Finally, :help [command]
will give detailed information about the commands.
Add some feeds
The :add
command can be used to add a feed. For example
:add http://example.com/rss :add http://example.com/secret.rss user=myuser password=secret
OPML import/export
If you’re coming from another RSS reader that can export OPML, you can import your list into canto by using canto-remote
from your shell.
user@host:~$ canto-remote import /path/to/feeds.opml
You can also export your feeds with the remote as well
user@host:~$ canto-remote export > feeds.opml
Delete feeds
With a feed selected, you can delete it with :del
Set your browser
Now that you’ve set up some feeds, it’d be nice to be able to read them.
:set browser firefox :set browser google-chrome-stable
If you’re a fan of text browsers, you can also tell canto to hand over the terminal
:set browser elinks :set browser.text True
You can then open a link in your browser with :goto
(which is bound to ‘g’ by default).
smartlink.py
The smartlink.py
plugin was written to give finer grain control over how links are handled with the :fetch
command that can be used anywhere :goto
can be. It can be used to properly handle media like images, video, audio, or other documents if your browser isn’t the best application to use. You can enable it by copying smartlink.py
from the installed plugin directory (/usr/lib/canto/plugins
by default) into your configuration’s plugin directory ~/.config/canto/plugins
and restarting canto-curses. The header of that plugin covers how to configure and use it.
The Reader
In addition to using a browser, canto-curses has a built in reader that can be used to read items. It can be opened with the :reader
command, which is bound to space by default.
Inside the reader, you can toggle displayed information
:show-links (l) :show-summary (s) :show-enclosures (e)
Within the reader, you can also open specific links with your browser by doing :goto [link number]
. :fetch [link number]
from the smartlink plugin will also work as expected.
reader-extras.py
A lot of feeds add extra information and easter eggs to items that you may be interested in showing in the reader. The reader-extras.py
plugin was created for just that purpose. You can enable it by copying reader-extras.py
from the installed plugin directory (/usr/lib/canto/plugins
by default) into your configuration’s plugin directory ~/.config/canto/plugins
. The plugin’s header has information on how to use it.
This plugin also has a debug mode that can be used to discover this extra content.
Organizing Feeds
Moving Them Up and Down
You can change the order of the feeds with the :promote
and :demote
commands, which are bound to + and – by default.
Collapsing (Minimizing) Feeds
Feeds can be reduced to single line summaries using :collapse
and :uncollapse
. By default, ‘c’ will toggle collapse for a single feed. ‘C’ and ‘V’ will collapse and uncollapse all visible feeds. This setting is persistent.
Categories
There are a handful of commands available to categorize feeds and filter based on those categories. For example, you can categorize a feed by selecting an item in that feed and doing
:categorize [category]
You can query what categories a feed is in by selecting an item in and doing
:categories
This will also tell you what categories you’ve already established.
Once you’ve marked your feeds, you can show only those feeds by doing
:show-category [category]
And switch back to the default view with
:show-category None
You can remove a feed from a category with
:remove-category [category]
Update Cycle
Since 0.9.0, Canto-curses has, by default, kept updates hidden until the user requests to see them with a refresh (bound to C-r by default) or an update (bound to \ or F5 by default). A refresh actually re-fetches all data from the daemon as if you just opened canto-curses. An update integrates new items into the list based on a policy and (optionally) a timer.
The reason that updating is manual by default is that RSS items appear frequently and changing the screen can be disorienting. It’s important to know if items before or after your cursor are new or old. It’s also important for range operations behave as expected so you don’t accidentally mark a whole bunch of items ‘read’ unintentionally because they appeared a millisecond before you triggered it. This is also why, by default, new items are appended to the ends of tags, it needs to be crystal clear both where and when new items will appear.
That said, this is open to interpretation, so there are a handful of knobs to tweak.
:set update.auto.enabled [True|False] :set update.auto.interval [n seconds]
You can set these to your desired settings and Canto will automatically cause an :update
every n seconds.
In addition, you can change where new items appear when they are updated.
:set update.style [prepend|maintain|append]
Where prepend will add items to the top of the feed, maintain will actively re-sort the feed on update to give output like :refresh
would give, equal to the order of items in the source feed data, and append (the default) will add items to the end of the tag.
Scrolling
You can alter the way Canto-curses scrolls through items as well.
:set taglist.cursor.type [edge|top|middle|bottom]
This setting will change where the cursor start scrolling. Edge is the default, where the cursor can move freely, and the interface scrolls only when it goes off screen. Top, middle, and bottom types keep the cursor as close to that point on the screen as possible while keeping the screen full of content.
:set taglist.cursor.edge [n lines]
This setting lets you set where exactly the “edge” of the screen is compared to the actual edge of the terminal. You could also think of this as a vertical “margin”. This affects all cursor types except “middle”
:set taglist.cursor.scroll [scroll|page]
This setting lets you switch between normal scrolling or paging. This only has an effect when the cursor type is “edge”.
Theming
Canto-curses gives you a lot of flexibility with it’s appearance.
Colors
The :color
command gives you fine-grain control over what color everything is. In it’s most basic form, you can specify it like this:
:color unread green
Which will make unread items green, instead of blue. See :help color
for a list of what you can change and the available colors.
256 colors
If your terminal supports it, and $TERM
is set to a 256-color compatible terminal, Canto natively supports 256 color, but you must specify a color by color code. A Perl script names colortest can be used to both test whether your terminal is properly setup and see what various colors look like.
user@host:~$ wget http://codezen.org/static/colortest -O colortest user@host:~$ chmod +x colortest user@host:~$ ./colortest
If this script displays more than 8 colors, you’re set and can use the simple numbers with :color
:color read 240
Style
Canto-curses also gives you control over the “style” of the text displayed. Most terminals support making text bold, dim, underlined, reversed or “standout”, all of which have different meanings based on your terminal. Sometimes you have to use these to achieve a color. For example, to get a gray with only 8 colors, you have to use the color black, but make it “bold”.
The :style
command works similar to :color
:style unread bold :style read normal
:help style
will give you more information on what you can change.
default-theme.py
If you’re not satisfied with just messing with colors and styles of what already exists, then you may be interested in default-theme.py
which implements the standard Canto theme in the form of a plugin. By copying default-theme.py
from /usr/lib/canto/plugins
to your plugin directory (~/.config/canto/plugins/
) you can then change most of what Canto puts on the screen. For control over the reader, see the previous section on reader-extras.py
Keybinds
To see a list of keybinds, use :help
. For help with commands, use :help commands
.
Using these two help pages, you can come up with your own string of commands to bind to a keybind, using :bind
. :help bind
will give you more info, but in short you can invoke it with an key or simple key chord.
:bind j item-state read \& next-item :bind C-y yank-link :bind M-y yank-title :bind F1 help
The first bind will reset the ‘j’ key to “item-state read & next-item” (note the \& in the invocation, it must be escaped or Canto will interpret that as a fresh command, similar to bash’s semicolon.) so when ‘j’ is pushed, it will set the current item as read and move to the next one automatically.
The subsequent binds use Ctrl-y (C-y), Alt-y (M-y – the M is for ‘meta’) and F1.
NOTE it’s important to use :bind
in the context you want to bind a key in. So, to make a bind work in the reader, use :bind
with the reader open. For example
(with Reader open) :bind 1 goto 1 :bind 2 goto 2 ...
To bind the number keys to go to specific links in the Reader text.
ALSO NOTE keybinds are persistent by nature and will be remembered between sessions of Canto-curses.
Synchronization
Currently, Canto supports two forms of synchronization between machines, both a plugins. Similar to all other plugins, you can enable these by copying from the installed plugin directory (/usr/lib/canto/plugins
) into your personal configuration plugin directory (~/.config/canto/plugins
).
sync-inoreader.py (0.9.2+)
This plugin, which requires the python3-requests package, will synchronize any items with Inoreader an online service that offers free accounts. The top of that file documents how to configure it and some caveats (such as needing a “real” Inoreader account and not an OAuth Google/Facebook login account).
Inoreader sync comes with some disadvantages, however. Because Inoreader as ad-based (with their free tier), the content they serve has ads in it. For this reason, and because Inoreader seems to have trouble fetching some feeds, Canto will still fetch data itself and try to match it with Inoreader’s data. This allows you access to the absolute most items, but at the cost that not all items will be synchronized. That means if you have multiple instances of Canto, all syncing with Inoreader, you will have unsynchronized items. Synchronization with other Inoreader clients (such as their web or mobile apps) works just fine.
To achieve perfect synchronization between multiple Cantos, you can use sync-rsync.py
sync-rsync.py
This rsync
based plugin actually synchronizes Cantos by rsync’ing their files to a common location. This can be used to rsync files to some remote storage space you have access to (via SSH, for example), or – since rsync works locally – can be used to sync with a service like Dropbox or Google Drive, or locally mounted NFS/sshfs filesystems.
This plugin also enables you to do canto-remote sync
to trigger a sync manually.
Other Plugins
These plugins didn’t fit into the rest of the configuration. As with the others, they can be enabled by copying them from the system plugin directory (/usr/lib/canto/plugins
) into your plugin directory (~/.config/canto/plugins
). Most of them include some amount of configuration.
reddit.py
This plugin will add Reddit API information to item titles. It can add the current number of upvotes, as well as the source subreddit. In addition, it adds a sort, reddit_score_sort
, which can be enabled by selecting any reddit tag and doing
:set tag.transform reddit_score_sort
autocmd.py
This plugin allows you to automatically issue commands on startup, potentially changing configuration amongst other things. It comes with an example that allows you to change your browser settings based on shell environment.
cleantitle.py
This plugin can do search and replace on story content to clean up badly formatted titles / descriptions. Useful to deal with unwanted newlines, improperly escaped HTML, or other arbitrary search and replaces.
xtermtitle.py
This plugin will set the title in most graphical terminals to “Canto” to make it easier to distinguish in your window manager. The title of the currently selected item can also be added.
yank.py
This plugin uses the program xclip
to put the title or the link of an item in your X clipboard.xclip
must be in your $PATH
somewhere. It attempts to bind ‘y’ to :yank-link
and ‘Y’ to :yank-title
but won’t clobber them if you’ve set them differently.
Tweaking Feed Options
You can configure individual feed settings to tweak how often the feeds are fetched, how long their items are kept and whether unread items can be discarded. With an item in the feed selected you can do:
:set feed.rate [rate in minutes] :set feed.keep_unread [True|False] :set feed.keep_time [time in seconds]
You can also change the defaults for feeds that haven’t already been specifically configured
:set defaults.rate [rate in minutes] :set defaults.keep_unread [True|False] :set defaults.keep_time [time in seconds]
For reference, the default rate
is 10 minutes, keep_unread
is False, and keep_time
is 86400 (one day).
Filtering and Sorting Items
The items shown in canto-curses can be filtered and sorted in various ways through something calls “transforms” that can change which items are present in the feeds and what order they’re in.
Global Filters and Sorts (Persistent)
By default, there is only one useful filter defined, filter_read
which will hide all items that you’ve marked as read by opening them in the browser/reader/fetch or by using ‘r’ (setting a feed as read) or ‘R’ (setting all items as read). You can enable this filter with
:set global_transform filter_read
Or disable it with
:set global_transform None
There’s also a proof of concept sort_alphabetical
transform, and the Reddit plugin adds a reddit_score_sort
as well. Transforms can be created on the fly or combined as well. For this advanced usage, read transform.py to see the various classes and operators provided.
Feed/Tag Filters and Sorts (Persistent)
In addition to settings for all clients, you can set transform per feed / tag. For example, to use the reddit_score_sort
from the Reddit plugin (in addition to having a copy of reddit.py
in your plugin directory), select an item in a Reddit feed and do
:set tag.transform reddit_score_sort
Client Filters and Sorts (Temporary)
The final level of transforms is on the client level and can be changed with :filter
, :transform
, or :sort
(which are all the same command). Unlike global and tag filters, these don’t persist between sessions because they aren’t written into the config. So, for example, to change to filter_read
for just the current session, you can do
:filter filter_read
Thank you very much for this software it’s been my main rss reader for years! Now in gentoo they are removing the 0.7 branch and I am “forced” to move to the canto-curses 0.9 branch. I am having trouble to port my configuration. Specially how do I configure colors in ~/.canto-ng/conf ?
Ahh disregard please my comment, I found the “color”: { “1”: 170} option for example.
This manual says: “Feeds can be reduced to single line summaries using :collapse and :uncollapse. By default, ‘c’ will collapse the selected feed and ‘v’ will uncollapse the selected feed. ‘C’ and ‘V’ will collapse and uncollapse all visible feeds. This setting is persistent.”
But ‘c’ toggles collapse, and ‘v’ does nothing.
My guess is that they simply need to update the docs. Seems that c to collapse and c to expand the single section makes sense.
Is it possible to sort the items in descending order?
How do you resurface an article that was marked and removed on update?
There must be an error in some of the units. It says “.keep_time [time in minutes]” and “keep_time is 86400 (one day)”. So probably kkep_time is seconds.
Absolutely right, keep_time is in seconds, updated, thanks.
Thank you for your great software!
In the old version (I guess 0.7) it was possible to get the number of unread items using ‘canto -a’.
Is there a similar option in the new version?
Yes, this is part of the remote now, `canto-remote status` is what you want for unread items, but it also takes some arguments that let you print the count for specific tags, read items, or total items too (see `canto-remote help status`)
Perfect! Is there a way to have feeds execute scripts? Like this in the old version: add(“script:feed.sh”)?
If you can update to git, I just wrote a simple plugin to do this. Just enable it (cp script.py into .config/canto/plugins and restart the daemon) and then you should be able to add “script:” feeds. More details in the top of the plugin.
Thank you!!
I added a feed requiring a username and password, but I specified the wrong password. How can I delete that feed as it is not listed at all. So :del doesn’t work.
If the feed doesn’t show up in :list then the daemon isn’t tracking it at all so it seems likely that the :add just failed. I’d just try again with the right password.
I installed canto from git on arch and for some reason when I enter the command canto-curses it says its not a command… am I missing something?
I suggest using the ‘canto-curses’ AUR package on Arch. Otherwise, installing from git I’d ensure that you installed from both the canto-curses and canto-next repos.
Thanks for the response I will try that.
Okay so I just stopped using the clean option after using makepkg and it works like a charm. Must of been installing then deleting itself for some reason.