(or emacs irrelevant)

Using digits to select company-mode candidates

I'd like to share a customization of company-mode that I've been using for a while. I refined it just recently, I'll explain below how.

Basic setting

(setq company-show-numbers t)

Now, numbers are shown next to the candidates, although they don't do anything yet:


Add some bindings

(let ((map company-active-map))
   (lambda (x)
     (define-key map (format "%d" x) 'ora-company-number))
   (number-sequence 0 9))
  (define-key map " " (lambda ()
                        (self-insert-command 1)))
  (define-key map (kbd "<return>") nil))

Besides binding 0..9 to complete their corresponding candidate, it also un-binds RET and binds SPC to close the company popup.

Actual code

(defun ora-company-number ()
  "Forward to `company-complete-number'.

Unless the number is potentially part of the candidate.
In that case, insert the number."
  (let* ((k (this-command-keys))
         (re (concat "^" company-prefix k)))
    (if (cl-find-if (lambda (s) (string-match re s))
        (self-insert-command 1)
      (company-complete-number (string-to-number k)))))

Initially, I would just bind company-complete-number. The problem with that was that if my candidate list was ("var0" "var1" "var2"), then entering 1 means:

  • select the first candidate (i.e. "var0"), instead of:
  • insert "1", resulting in "var1", i.e. the second candidate.

My customization will now check company-candidates—the list of possible completions—for the above mentioned conflict. And if it's detected, the key pressed will be inserted instead of being used to select a candidate.


Looking at git-log, I've been using company-complete-number for at least 3 years now. It's quite useful, and now also more seamless, since I don't have to type e.g. C-q 2 any more. In any case, thanks to the author and the contributors of company-mode. Merry Christmas and happy hacking in the New Year!

Comparison of transaction fees on Patreon and similar services

On December 7, Patreon made an announcement about the change in their transaction fee structure. The results as of December 10 speak for themselves:

December 2017 summary: -$29 in pledges, -6 patrons

All leaving patrons marked "I'm not happy with Patreon's features or services." as the reason for leaving, with quotes ranging from:

The billing changes are not great.


Patreon's new fees are unacceptable

In this article, I will explore the currently available methods for supporting sustainable Free Software development and compare their transaction fees.

My experience

My experience taking donations is very short. I announced my fund raising campaign on Patreon in October 2017.

Here's what I collected so far, vs the actual money spent by the contributors:

  • 2017-11-01: $140.42 / $162.50 = 86.41%
  • 2017-12-01: $163.05 / $187.50 = 86.96%

The numbers here are using the old Patreon rules that are going away this month.

Real numbers

method formula charged donated fee
old Patreon ??? $1.00 $0.86 14%
new Patreon 7.9% + $0.35 $1.38 $0.95 31%
    $2.41 $1.90 21%
    $5.50 $4.75 14%
OpenCollective 12.9% + $0.30 $1.33 $0.90 32%
    $2.36 $1.80 24%
    $5.45 $4.50 18%
Flattr 16.5% $1.00 $0.84 17%
    $2.00 $1.67 17%
    $5.00 $4.18 17%
Liberapay 0.585% $1.00 $0.99 1%

On Patreon

Just like everyone else, I'm not happy with the incoming change to the Patreon fees. But even after the change, it's still a better deal than OpenCollective, which is used quite successfully e.g. by CIDER.

Just to restate the numbers in the table, if all backers give $1 (which is the majority currently, and I actually would generally prefer 5 new $1 backers over 1 new $5 backer), with the old system I get $0.86, while with the new system it's $0.69. That's more than 100% increase in transaction fees.

On OpenCollective

It's more expensive than the new Patreon fees in every category or scenario.

On Flattr

Flattr is in the same bucket as Patreon, except with slightly lower fees currently. Their default plan sounds absolutely ridiculous to me: you install a browser plug-in so that a for-profit corporation can track which websites you visit most often in order to distribute the payments you give them among those websites.

If it were a completely local tool which doesn't upload any data on the internet and instead gives you a monthly report to adjust your donations, it would have been a good enough tool. Maybe with some adjustments for mind-share bubbles, which result in prominent projects getting more rewards than they can handle, while small projects fade away into obscurity without getting a chance. But right now it's completely crazy. Still, if you don't install the plug-in, you can probably still use Flattr and it will work similarly to Patreon.

I made an account, just in case, but I wouldn't recommend going to Flattr unless you're already there, or the first impression it made on me is wrong.

On Paypal

Paypal is OK in a way, since a lot of the time the organizations like Patreon are just middle men on top of Paypal. On the other hand, there's no way to set up recurring donations. And it's harder for me to plan decisions regarding my livelihood if I don't know at least approximately the sum I'll be getting next month.

My account, in case you want to make a lump sum donation: paypal.me/aboabo.

On Bitcoin

Bitcoin is similar to Paypal, except it also:

  • has a very bad impact on the environment,
  • is a speculative bubble that supports either earning or losing money without actually providing value to the society.

I prefer to stay away from Bitcoin.


Liberapay sounds almost too good to be true. At the same time, their fees are very realistic, you could almost say optimal, since there are no fees for transfers between members. So you can spend either €20.64 (via card) or €20.12 (via bank wire) to charge €20 into your account and give me €1 per month at no further cost. If you change your mind after one month, you can withdraw your remaining €19 for free if you use a SEPA (Single Euro Payments Area) bank.

If I set out today to set up a service similar to Liberapay, even with my best intentions and the most optimistic expectations, I don't see how a better offer could be made. I recommend anyone who wants to support me to try it out. And, of course, I will report back with real numbers if anything comes out of it.

Thanks to all my patrons for their former and ongoing support. At one point we were at 30% of the monthly goal (25% atm.). This made me very excited and optimistic about the future. Although I'm doing Free Software for almost 5 years now, it's actually 3 years in academia and 2 years in industry. Right now, I'm feeling a burnout looming over the horizon, and I was really hoping to avoid it by spending less time working at for-profit corporations. Any help, either monetary or advice is appreciated. If you're a part of a Software Engineering or a Research collective that makes you feel inspired instead of exhausted in the evening and you have open positions in EU or on remote, have a look at my LinkedIn - maybe we could become colleagues in the future. I'll accept connections from anyone - if you're reading this blog, we probably have a lot in common; and it's always better together.

Ivy 0.10.0 is out


Ivy is a completion method that's similar to Ido, but with emphasis on simplicity and customizability.


The current release constitutes of 280 commits and 8 months of progress since 0.9.0. Many issues ranging from #952 to #1336 were fixed. The number of people who contributed code as grown to 91; thanks, everyone!

Details on changes

Changelog.org has been a part of the repository since 0.6.0, you can get the details of the current and past changes:


Many improvements are incremental and don't require any extra code to enable. I'll go over a few selected features that require a bit of information to make a good use of them.

Selectable prompt

Off by default. You can turn it on like so:

(setq ivy-use-selectable-prompt t)

After this, your current input becomes selectable as a candidate. Press C-p when you're on the first candidate to select your input instead.

This solves the long standing issue of e.g. creating a file or a directory foo when a file foobar already exists. Previously, the only solution was to use C-M-j. It's still available, but now you can also select your input with C-p and press RET.

New global actions for ivy

ivy-set-actions was used to enable the following bindings:

  • Press M-o w to copy the current candidate to the kill ring.
  • Press M-o i to insert the current candidate into the buffer.

These bindings are valid for any completion session by default.

Use C-d in ivy-occur buffers

Here's an example use-case: search your source code for a variable name with e.g. counsel-rg and call ivy-occur (C-c C-o). Suppose you get 10 results, only 4 of which are interesting. You can now delete the uninteresting ones with C-d. Then maybe check off the others with C-d as well as you complete them one by one. A sort of a TODO list.

Similarly, if you want to go over variables to customize, you can call counsel-describe-variable with input ^counsel-[^-] and then check off the ones you have already examined with C-d.

Defcustoms to play with

Here's the list of new defcustom or defvar that might be interesting to review:

  • counsel-async-filter-update-time
  • counsel-async-ignore-re
  • counsel-describe-function-function
  • counsel-describe-function-preselect
  • counsel-find-file-ignore-regexp
  • counsel-fzf-dir-function
  • counsel-git-grep-skip-counting-lines
  • counsel-git-log-split-string-re
  • counsel-url-expansions
  • ivy-auto-select-single-candidate
  • ivy-magic-slash-non-match-action
  • ivy--preferred-re-builders
  • ivy-truncate-lines

New Commands

14 new commands were added by me and many contributors. Here's the list:

  • counsel-ack - completion for ack
  • counsel-apropos - completion for apropos
  • counsel-file-register - completion for file registers
  • counsel-fzf - completion for fzf
  • counsel-git-change-worktree - completion for git-worktree
  • counsel-git-checkout - completion for git-checkout
  • counsel-minibuffer-history - generalization of counsel-expression-history and counsel-shell-command-history
  • counsel-org-capture - completion for org-capture
  • counsel-org-file - browse all attachments for the current Org file
  • counsel-org-goto - completion for Org headings
  • counsel-org-goto-all - completion for Org headings in all open buffers
  • counsel-switch-to-shell-buffer - switch to a shell buffer, or create one
  • ivy-occur-delete-candidate - delete current candidate in ivy-occur-mode
  • ivy-switch-view - select a window configuration, decoupled from ivy-switch-buffer

My personal favorites are counsel-fzf and counsel-org-file.


Again, thanks to all the contributors. Happy hacking!

P.S. Please consider joining my 74 patrons to give me the opportunity to work on Free Software a lot more. We are currently at 30% of the goal.

Save Ivy file completions to Dired


I think ivy-occur (C-c C-o) is one of the coolest features in ivy. It allows you to save your current search into a new buffer. This has many uses:

  • get a full overview of all candidates
  • many useful modal bindings (q, j, k, f) and mouse support
  • ability to manipulate candidates as text
  • save the search for later, with the option to refresh the search with g
  • go over candidates as a TODO list, using C-d to remove elements

Everything above works for any ivy-read session. But the most powerful features come into play when ivy-occur gets customized for a specific collection.

ivy-occur for grep-like functions

(ivy-set-occur 'swiper 'swiper-occur)

Thanks to this default customization, the resulting *ivy-occur swiper* buffer is in ivy-occur-grep-mode which inherits from grep-mode. Additionally, you can use ivy-wgrep-change-to-wgrep-mode C-x C-q to edit the result in-place - pressing C-x C-s will save the changes.

Similar customizations are available for counsel-git-grep, counsel-ag, counsel-rg, and counsel-grep.

ivy-occur for ivy-switch-buffer

(ivy-set-occur 'ivy-switch-buffer 'ivy-switch-buffer-occur)

This makes C-c C-o open your candidates in the powerful ibuffer, which adds additional info to your buffer list and allows you to manipulate buffers easily.

For instance, to delete all matching buffers you can do C-c C-o tD.

The source code is short enough to be included here:

(defun ivy-switch-buffer-occur ()
  "Occur function for `ivy-switch-buffer' using `ibuffer'."
  (ibuffer nil (buffer-name) (list (cons 'name ivy--old-re))))

The interface is quite simple: ivy-occur is responsible for generating a new buffer, and the occur function e.g. ivy-switch-buffer-occur is to fill that buffer with useful info, based on the current search parameters like ivy-text and ivy--old-re.

ivy-occur for counsel-find-file-like functions

This is a brand new feature that works for counsel-find-file, counsel-git, and counsel-fzf (which itself is quite new, thanks to @jojojames for contributing it).

Since these functions are used to complete file names, we obviously want ivy-occur to open a Dired buffer.

Example 1

To delete all *.elc files in the current folder do:

  • C-x C-f elc$ C-c C-o tDy.

Example 2

To copy all Org files in a Git project to some directory do:

  • M-x counsel-git org$ C-c C-o tC.

Example 3

To get a list of videos to watch do:

  • M-x counsel-fzf mp4$ C-c C-o.

I can further e.g. mark 3 files with m and use r to send these 3 files to vlc as a list. See this post for my dired setup that makes r work this way.

You can remove some files afterwards with the usual D or dx. And to redisplay the buffer use g.


I hope you like the new feature. I had a really good few hours figuring out how it should work exactly. Please consider joining my 72 patrons to give me the opportunity to work on Free Software a lot more. Happy hacking!

Orca - new package to improve org-capture from browser


Orca is a new Emacs package, an attempt to refactor my old org-fu into something that's much more re-usable and easier to get started with.

Orca functionality


When capturing from Firefox using org-protocol (together with this addon):

  • either I refile each time I capture, which is slow
  • or my captures pile up in one place, which is messy


  1. Define rules for where links from certain websites should be captured.
  2. Allow to capture directly into the current org-mode buffer, since it's likely related to what I'm working with on.

Part 1: Rules example

Here is my example list of configurations:

Corresponding code:

(setq orca-handler-list
         "~/Dropbox/org/wiki/emacs.org" "Reddit")
         "~/Dropbox/org/wiki/emacs.org" "\\* Questions")
         "~/Dropbox/org/ent.org" "\\* Articles")))

Part 2: Current buffer example

For example, I'm researching how to implement something with docker. This means that I have docker.org open, along with dozens of tabs in the browser.

I can configure to capture into the current org-mode buffer with a * Tasks heading like this:

(push '(orca-handler-current-buffer "\\* Tasks") orca-handler-list)

Since docker.org has * Tasks, I just click the capture button in Firefox and follow up with an immediate C-c C-c in Emacs. The link is already in the right position, no need for an extra refile step.

Using customize with orca

You can set up the capture rules using M-x customize-group RET orca RET.

Here's a screenshot: orca-customize

As you see, the customization is a list of an arbitrary length, with each element falling into one of three categories, each backed by an Elisp function (orca-handler-current-buffer, orca-handler-file, and orca-handler-match-url). Each function takes a different number of arguments (one, two, and three, respectively) - they are all annotated by the interface.

Here's the code that describes the expected :type to customize:

(defcustom orca-handler-list
  ;; ...
  :type '(repeat
            :tag "Current buffer"
            (const orca-handler-current-buffer)
            (string :tag "Heading"))
            :tag "URL matching regex"
            (const orca-handler-match-url)
            (string :tag "URL")
            (string :tag "File")
            (string :tag "Heading"))
            :tag "Default"
            (const orca-handler-file)
            (string :tag "File")
            (string :tag "Heading")))))

You can read more about the customization types in this manual section.


I hope you enjoy orca. I've submitted it to MELPA. Hopefully, it will be available for an easy install very soon.

Org-mode is a beautiful thing, but my previous attempts to configure it were huge config files of loosely related (i.e. the only thing in common was Org-mode) stuff spanning hundreds of lines. Orca is an improvement in this respect, since it focuses on a very narrow domain. It still tries to be flexible (just like org-capture) - you can plug in your own functions into orca-handler-list. But initially, the flexibility can be constrained into the customize-group interface, to allow for a self-documenting solution that's easy to get started with. Happy hacking!

PS. Thanks to all my patrons for advancing my Patreon campaign! As of this writing, we're almost at the 25% mark with 61 contributors.