- Automate something you already do.
- List tools and make connections, see what becomes possible
How to write a Kupfer plug-in
Kupfer is quite useful without extra plug-ins. However, when a service you use is not provided, it becomes quite hard (or impossible) to work with it without a plug-in. To write a plug-in for Kupfer does not need to be difficult as there is a lot of functionality provided for first time plug-in writers.
What to add
There are three types of classes that you can add to Kupfer: Sources, Actions, and Leafs. You extend the functionality of Kupfer by adding one or more classes of these types.
A Source is a collection of items. Examples are "Firefox Bookmarks", "Directories", "Files", "Windows", "Albums", or "Songs". The items inside a Source are called Leafs.
A Leaf is an item in Kupfer. You can search or create a Leaf by typing some text. Examples are text, URL, host, file, directory, or a music album. After you select a Leaf, you can search for an Action.
Some actions are Leafs. These are called RunnableLeafs. A RunnableLeaf is something that doesn't need a Leaf subject. An example of this is "Restart".
An Action is a type that processes the Leaf. Examples are "Open File", "Go to URL", "Delete File", and "Open".
When you create a plug-in you create one or more of these types. You don't need all three. It's possible (and expected) to reuse the Source, Leaf, and Action types. You can add a Source that adds items of type UrlLeaf. An example is a bookmark source.
You can add an Action that works with existing Leafs. An example of a core action that does this is the AppendTo action, that appends text to a file.
Kupfer contains a few default action utilities. Examples are show_url or launch_commandline. In your plug-in, you format the url and call utils.show_url(url) to automatically open a URL in a browser.
When your plugin uses settings, it's possible to add a few lines to the plugin to get input fields on the plugin configuration. This configuration is automatically loaded when the plugin is activated. You don't need to provide this yourself.
Where to start
User-defined plugins can be added to ~/.local/share/Kupfer/plugins/. When you quit and restart Kupfer, Plugins are reloaded. You need to enable the plugin in the plugin settings.
A good way to start with a plugin is to add a layer around a website. Some websites have a way to pre-fill a form with values. Fastmail has the compose URL `https://www.fastmail.com/mail/compose` which takes the query parameters `to`, `subject`, and `body`. When you add these parameters to the URL the form will be pre-filled with this information.
We could write a plugin like this. You create an action that opens this URL with the contacts that you found. Kupfer already has a ContactLeaf with an email address. There is an example of an Action in `clawsmail.py` that gathers contacts. In the case of Fastmail, you can call `utils.show_url` with the right url to open the window where you can finish the email.
Another way is to add a layer around a command-line program. An example is the command `brotab`, which allows us to activate or close tabs. The source would call `brotab list` and provide the tabs as Leafs. Two actions that we would add or Activate and Close Tab, which would call `brotab activate <tab_id>` and `brotab close <tab_id>`.
The third way to start is by calling into a library. It is useful to use a library because Kupfer itself doesn't need that much code. An example could be a Pinboard plugin. There is a library for Pinboard that can return the bookmarks. The plugin would add a Source for these bookmarks and return UrlLeafs. The user can use URLs with the actions that are available in Kupfer by default.
Writing a plugin for Kupfer does not have to be hard. There are examples already for different types of functionality. You can use websites, command-line tools, and libraries to make information available or perform an action. You can place the plugin in a specific directory in your home folder to make it available in Kupfer. You can add settings with a few lines of code.