(or emacs irrelevant)

hydra 0.15.0 is out

This release consists of 45 commits done over the course of the last 2 years. With this version, I have introduced a Changelog.org, similar to what ivy and avy have.



Display hints using posframe

A new defcustom hydra-hint-display-type was introduced that can be either lv (the default), message, or posframe.

Posframe is a package that leverages a new feature in Emacs 26.1: the ability to display child frames. The advantage of using child frames is that you can easily position them anywhere within your frame area. For example, the default setting is to put it in the center of the current window, which is closer to where your eyes are focused than the minibuffer. Child frames don't interfere with the content of the buffers which they overlap. Finally, you can select a different font for the child frame.


Less boilerplate in defhydra

You no longer have to add :hint nil, and you can skip the docstring as well:

(defhydra hydra-clock (:exit t)
  ("q" nil "quit" :column "Clock")
  ("c" org-clock-cancel "cancel" :column "Do" :exit nil)
  ("d" org-clock-display "display")
  ("e" org-clock-modify-effort-estimate "effort")
  ("i" org-clock-in "in")
  ("j" org-clock-goto "jump")
  ("o" org-clock-out "out")
  ("r" org-clock-report "report"))

Add heads to an existing hydra

You can now add heads to an existing hydra like this:

(defhydra hydra-extendable ()
  ("j" next-line "down"))

(defhydra+ hydra-extendable ()
  ("k" previous-line "up"))

The new macro defhydra+ takes the same arguments as defhydra, so it's quite easy to split up or join your hydras.

The use case of defhydra+ is when you have many packages that want to add heads to an existing hydra. Some of them may be optional or loaded lazily.

You can now have a base defhydra, and then use defhydra+ to add heads to it when a new package is loaded. Example:

(defhydra hydra-toggle ()
  ("q" nil "quit" :column "Exit")
  ("w" whitespace-mode
       (format "whitespace-mode: %S" whitespace-mode)
       :column "Toggles"))

(use-package org
  (defhydra+ hydra-toggle ()
    ("l" org-toggle-link-display
         (format "org link display: %S" org-descriptive-links))))


Big thanks to all contributors, and I hope you enjoy the new release. Happy hacking!

PS. Thanks to everyone who supports me on Liberapay and Patreon!

avy 0.5.0 is out

This release consists of 109 commits done over the course of the last 3 years by me and many contributors. Similarly to the 0.4.0 release, the release notes are in Changelog.org. I recommend reading them inside Emacs.



A lot of new code is just straight upgrades, you don't need to do anything extra to use them. Below, I'll describe the other part of the new code, which is new commands and custom vars.

New API functions

New functions have been added as drop-in replacements of double-dash (private) Avy functions that were used in other packages and configs. Please replace the references to the obsolete functions.

  • avy-jump is a drop-in replacement of avy--generic-jump,
  • avy-process is a drop-in replacement of avy--process.

New dispatch actions

The concept of dispatch actions was introduced in 0.4.0. Suppose you have bound:

(global-set-key (kbd "M-t") 'avy-goto-word-1)

and a word that starts with a "w" and is select-able with "a". Here's what you can do now:

  • M-t w a to jump there
  • M-t w x a - avy-action-kill-move: kill the word and move there,
  • M-t w X a - avy-action-kill-stay: kill the word without moving the point,
  • M-t w i a - avy-action-ispell: use ispell/flyspell to correct the word,
  • M-t w y a - avy-action-yank: yank the word at point,
  • M-t w t a - avy-action-teleport: kill the word and yank it at point,
  • M-t w z a - avy-action-zap-to-char: kill from point up to selected point.

You can customize avy-dispatch-alist to modify these actions, and also ensure that there's no overlap with your avy-keys, if you customized them.

New avy-style setting: 'words

You can now customize:

(setq avy-style 'words)

And you'll see overlays like "by", "if", "is", "it", "my" for 2-letter sequences, and "can", "car", "cog" for 3-letter sequences. You might find them easier to type than "hla", "lls" and "jhl". But you will have to adjust your avy-dispatch-alist, e.g. to use only upper case characters.



This is feature is a mix of linum-mode and ace-window-display-mode. You'll see the overlays when you enable this mode, so that there's less context switch when you call avy-goto-line.

Suppose you jumped to a word that starts with "a". Now you want to jump to a different word that also starts with "a". You can use avy-resume for this.

Additionally, you can use avy-next and avy-prev to cycle between the last avy candidates. Here's an example hydra to facilitate it:

(defhydra hydra-avy-cycle ()
  ("j" avy-next "next")
  ("k" avy-prev "prev")
  ("q" nil "quit"))

(global-set-key (kbd "C-M-'") 'hydra-avy-cycle/body)


Big thanks to all contributors, and I hope you enjoy the new release. Happy hacking!

Change the current time in Org-mode


I'm constantly amazed by other people's Org workflows. Now that the weekly tips are a thing, I see more and more cool Org configs, and I'm inspired to get more organized myself.

My own Org usage is simplistic in some areas, and quite advanced in others. While I wrote a lot of code to manipulate Org files ( worf, org-download, orca, org-fu, counsel), the amount of Org files and TODO items that I have isn't huge:

(counsel-git "org$ !log")
;; 174 items

(counsel-rg "\\* DONE|CANCELLED|TODO")
;; 8103 items

Still, that's enough to get out-of-date files: just today I dug up a file with 20 outstanding TODO items that should have been canceled last November!

How to close 20 TODOs using a timestamp in the past

When I cancel an item, pressing tc (mnemonic for TODO-Cancel), Org mode inserts a time stamp with the current time. However, for this file, I wanted to use October 31st 2018 instead of the current time. Org mode already has options like org-use-last-clock-out-time-as-effective-time, org-use-effective-time, and org-extend-today-until that manipulate the current time for timestamps, but they didn't fit my use case.

So I've advised org-current-effective-time:

(defvar-local worf--current-effective-time nil)

(defun worf--current-effective-time (orig-fn)
  (or worf--current-effective-time
      (funcall orig-fn)))

(advice-add 'org-current-effective-time
            :around #'worf--current-effective-time)

(defun worf-change-time ()
  "Set `current-time' in the current buffer for `org-todo'.
Use `keyboard-quit' to unset it."
  (setq worf--current-effective-time
        (condition-case nil
            (org-read-date t 'totime)
          (quit nil))))

A few things of note here:

  • worf--current-effective-time is buffer-local, so that it modifies time only for the current buffer
  • I re-use the awesome org-read-date for a nice visual feedback when inputting the new time
  • Instead of having a separate function to undo the current-time override, I capture the quit signal that C-g sends.


The above code is already part of worf and is bound to cT. I even added it to the manual. I hope you find it useful. Happy organizing!

Swiper-isearch - a more isearch-like swiper


Since its introduction in 2015, swiper, while nice most of the time, had two problems:

  1. Slow startup for large buffers.
  2. Candidates were lines, so if you had two or more matches on the same line, the first one was selected.

Over time, workarounds were added to address these problems.

Problem 1: slow startup

Almost right away, calling font-lock-ensure was limited to only small enough buffers.

In 2016, counsel-grep-or-swiper was introduced. It uses an external process (grep) to search through large files.

In 2017, I found ripgrep, which does a better job than grep for searching one file:

(setq counsel-grep-base-command
      "rg -i -M 120 --no-heading --line-number --color never %s %s")

The advantage here is that the search can be performed on very large files. The trade-off is that we have to type in at least 3 characters before we send it to the external process. Otherwise, when the process returns a lot of results, Emacs will lag while receiving all that output.

Problem 2: candidates are lines

In 2015, swiper-avy was added, which could also be used as a workaround for many candidates on a single line. Press C-' to visually select any candidate on screen using avy.

Enter swiper-isearch

Finally, less than a week ago, I wrote swiper-isearch to fix #1931.

Differences from the previous commands:

  • Every candidate is a point position and not a line. The UX of going from one candidate to the next is finally isearch-like, I enjoy it a lot.

  • Unlike swiper, no line numbers are added to the candidates. This allows it to be as fast as anzu.

  • Unlike counsel-grep, no external process is used. So you get feedback even after inputting a single char.

I like it a lot so far, enough to make it my default search:

(global-set-key (kbd "C-s") 'swiper-isearch)


Try out swiper-isearch, see if it can replace swiper for you; counsel-grep-or-swiper still has its place, I think. Happy hacking!

PS. Thanks to everyone who supports me on Liberapay and Patreon!

PPS. Thanks to everyone who contributes issues and patches!

Progress bars for apt in shell


For a couple years now, I use M-x shell as my main shell. Recently, I have fixed one of the minor annoyances that go along with using shell in Emacs. At least since Ubuntu 18.04, the terminal "progress bar" feature, displayed below is non-optional:


It uses terminal escape codes to display the progress bar, and shell-mode can't handle them well, so they clobber a lot of the output.

Initial work around

Previously, I was using this work around, since apt-get doesn't display the progress bar:

# sudo apt upgrade
sudo apt-get upgrade

Progress bar in the mode line

But typing 4 extra chars is hard. And apt-get will likely get these progress bars at some point as well. So I spent around an hour of my weekend hacking an Elisp solution. Here is the code:

 :before 'ora-ansi-color-apply-on-region)

(defun ora-ansi-color-apply-on-region (begin end)
  "Fix progress bars for e.g. apt(8).
Display progress in the mode line instead."
  (let ((end-marker (copy-marker end))
      (goto-char (copy-marker begin))
      (while (re-search-forward "\0337" end-marker t)
        (setq mb (match-beginning 0))
        (when (re-search-forward "\0338" end-marker t)
            (delete-and-extract-region mb (point))
            2 -2)))))))

(defun ora-apt-progress-message (progress)
  (setq mode-line-process
        (if (string-match
             "Progress: \\[ *\\([0-9]+\\)%\\]" progress)
             (concat ":%s "
                     (match-string 1 progress)
                     "%%%% "))

The solution will detect e.g. "\0337...Progress: [ 25%]...\0338", remove it from the shell buffer and display "25%" in the mode line instead.

Use the Echo Area instead of the mode line

The above is a good enough solution specifically for apt(8), but not for the generic case. Let's try to emulate how e.g. gnome-terminal handles these escape sequences. It takes sequences like "\0337.*\0338" and displays them in the bottom of the window. Kind of like the Emacs Echo Area. That's easy enough to do:

(defun ora-apt-progress-message (progress)
    "%" "%%"
    (ansi-color-apply progress))))

Above, we use ansi-color-apply to get rid of any extra terminal escape codes. I decided to stay with the Echo Area version instead of the mode line version. Here's how it looks like:


You can find all of the above code in my config. Happy hacking!