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 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).

The 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 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.

A lot of feeds add extra information and easter eggs to items that you may be interested in showing in the reader. The plugin was created for just that purpose. You can enable it by copying 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.


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


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 [True|False]
:set [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 [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.


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”.


Canto-curses gives you a lot of flexibility with it’s appearance.


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 -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


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.

If you’re not satisfied with just messing with colors and styles of what already exists, then you may be interested in which implements the standard Canto theme in the form of a plugin. By copying 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


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.


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). (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

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.

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

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.

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.

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.

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 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 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

19 thoughts on “Manual

  1. 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 ?

  2. 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.

    1. 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.

  3. 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.

  4. 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?

    1. 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`)

      1. Perfect! Is there a way to have feeds execute scripts? Like this in the old version: add(“”)?

        1. If you can update to git, I just wrote a simple plugin to do this. Just enable it (cp 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.

  5. 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.

    1. 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.

  6. 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?

    1. 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.

      1. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *