An Elisp implementation of Rofi

40a25c7 Add TODO: Implement run (and drun) like program launching modi

8 months ago

7011f29 Minor text format fixup in README

1 year, 3 months ago
  1. rofi-in-elisp
    1. Introduction
      1. What has been Implemented (so far)
    2. How it Works
    3. Installation
    4. Setup
      1. i3
    5. Roadmap
    6. Similar Projects
    7. Contributing




I started using Rofi shortly after switching to i3. I even wrote some modi (modes) for Rofi (which were never published). However, fairly quickly I started running into what I felt were limitations in Rofi.1 So eventually I got the idea, why not just implement something like Rofi, except in Elisp? Because, as an Emacs user, that's probably what I really wanted to do, anyway, amirite? :) And so, here we are.

#What has been Implemented (so far)

In fairness, I cannot really call this a full implementation of Rofi, by any stretch. Out of the box, Rofi does many things. Out of the following list, only things that have been checked off have been implemented (so far):

  • [X] web search

  • [ ] launch programs

  • [ ] switch windows

  • [ ] launch ssh sessions

  • and many others (but above are the main ones)

Now, this is not due to any techical limitation. In fact what I wrote so far is pretty general and I plan to add more modi (modes) to it at some point. I am also willing to accept patches. It's simply that the web search was the first thing that was most important to me, and so that's what I implemented first.

Some of those (mainly launching ssh session) I will probably never get around to, as we have Tramp for that.

#How it Works

Invoke the included rofi-in-elisp-launcher shell script with a single argument, the modi (or mode) that you want to launch. Example: rofi-in-elisp-launcher web to launch the web search modi. That modi gets passed from the shell script to the rofi-in-elisp function as its only required argument.

  • Note: You probably want to bind each modi (mode) to some keybinding, for convenience (more on that in the Setup section).


So far this package is not in any of the popular online repositories. Although I did try and follow the standard Emacs Lisp packaging guidelines.

Therefore the easiest (and best, considering updates) way currently is probably just to git clone this repository somewhere on your machine, and then invoke either package-install-from-buffer or package-install-file 2 on rofi-in-elisp.el. I did include a version number, so you should be able to manually update this way in the future.3

The main (and only) function, rofi-in-elisp is tagged with an autoload magic cookie, so if you follow the above installation procedure, you should not need to require this package. Although doing so might make the very first invocation ever so slightly faster (not sure, really)?

Having said all the above, this is the very first Elisp package I ever released publicly. I tried to study dilligently the relevant information, and I feel reasonably confident I have done things correctly. However, as it's still my first go around, any feedback would be welcomed.


  • For this program to work, Emacs needs to be running as a daemon/server. This is because the rofi-in-elisp-launcher shell script opens a pop-up window by calling emacsclient (mostly for performance reasons).

  • You probably want to bind some key to launch the rofi-in-elisp-launcher shell script at the OS level.

In my case, I use i3, so I have included instructions on how to set this up, below.

  • Setting up keybindings will vary per window manager, of course. I am willing to accept additions to this document with instructions for other window managers.


  • There are 2 things we need to set up in i3:

    1. We have to set the window to float (this is not needed in non-tiling window managers, where all windows are "floating").

    2. We want to bind a key to launch the rofi-in-elisp-launcher shell script.

  • Here is how to do that, in i3 (following would be put in ~/.config/i3/config for example):

    # make window float
    # Note: pixel window width is my preference, adjust accordingly.
    for_window [class="^Emacs$" title="^floating$"] floating enable border pixel 3
    # bind key
    # Assuming you have already set your $mod key to Super (Win):
    set $mod Mod4
    # Then you would add something like the following to launch the web search modi
    # with (s-b):
    bindsym $mod+b exec ~/full/path/to/rofi-in-elisp-launcher web
    # Currently, there are no other modi, but eventually there will be, just bind
    # them to other keys like so (where 'new' is the name of some new modi):
    bindsym $mod+n exec ~/full/path/to/rofi-in-elisp-launcher new


I prefer to track my tasks (all tasks, whether software or other project related) in Orgmode. They used to be right here, but that's to messy for a README, so I moved them to their own file in ROADMAP.org.4

I still plan on interacting with the public through the Issue tracker that sr.ht provides, but you may want to check the above file before lodging an issue.

To be honest, combining the two into some workflow I can live with is going to be an interesting experiment, but we will see how it goes.

#Similar Projects

There is a nice list (with some comparison notes) in the Similar Projects section of the README for counsel-web.

One of those, is engine-mode, who in turn list a few more examples of search strings which could easily be adapted into rofi-in-elisp (or elsewhere).

I don't use engine-mode, but after watching a nice presentation about it, I began to realize a few things, and so I made a table:

  rofi-in-elisp engine-mode
Call from anywhere in OS Emacs only
Functions one one per engine
Clipboard available yes no(?)
Selection available yes no
Selection pre-populated no yes
History searchable yes no


In case you did not notice, I keep the primary copy of this README in Orgmode (README.org), and then I generate the Markdown (README.md) from that.

This is strictly so it renders nicely here on sr.ht (where only Markdown is supported).

Because in general, I agree with Karl Voit that Org-Mode Is One of the Most Reasonable Markup Languages to Use for Text and therefore I greatly prefer it to Markdown, for all the reasons mentioned in that article (and thus, no need to repeat them here).


1 In fairness, since using Emacs and especially since learning a bit of Elisp I have probably become spoiled by becoming accustomed to do pretty much whatever I want.

2 The latter just calls the former (I learned today while troubleshooting).

3 Until this package gets into some package archive (which is something I never have done before, either) the best way to be updated of new versions is probably to check (or subscribe to) the mailing list.

4 Which I would like to link from here, except for the following problem. I have sporadically attempted various ways of publishing 'Orgmode files with todos' to Markdown (or HTML) from Orgmode, so they may be nicely rendered in Sourcehut's web UI, but each way I have tried so far is unsatisfactory for one reason or another. Since I don't have the time right now to dig into this any further, and Drew/Sourcehut still officially continue to refuse Orgmode support, things will have to remain this way for the time being. You will have to look at ROADMAP.org in its (ugly) plaintext web representation here, or (recommended) just clone the repo or save the file so you can view it locally in native Orgmode.