Where parallels cross

Interesting bits of life

Extending Nyxt via Emacs: how to leverage Common Lisp wealth to get your links as QR codes

Too long; didn't read

Common Lispers are amazing people! There are a lot of elegant libraries around. You can extend Nyxt with those. Here you can learn how to make a QR code of the URL you are currently visiting with the amazing cl-qrencode library.

The problem

I already knew that Common Lisp has an amazing package manager: Quicklisp. That is a trove of treasures! I had been wondering how to inject that tool in Nyxt. Just today I was checking new posts about Nyxt, and I found out that the user publicvoit likes to make QR code of the page he is visiting to navigate it with his phone.

I became curious and I went looking if Common Lisp had something for that and I found the library cl-qrencode!

Then I wondered again: how easy would be to inject that in Nyxt and make publicvoit happy?

It is a problem indeed

The main issue here is how to welcome the fantastic features and libraries of Common Lisp in Nyxt. How amazing would it be to have this vast treasure-box available to extend our browser? (Oh my, Natural Language Processing for your open tabs!)

And there is a solution

Then let's discover how difficult is to make a QR code of the page we are visiting at the moment.

First, I assume you installed Quicklisp already. If not, here is how to do that.

After the installation you should have this file: ~/quicklisp/setup.lisp.

Second, I assume you can run Slime connected to Nyxt. If not, give a look at my repo for instructions.

Then we are ready to extend!

We start from loading Quicklisp in our Nyxt REPL!

(load "~/quicklisp/setup.lisp")

That is so simple that I cannot believe it. Quicklisp is too cool! Let me show why. We want to transform the URL we are navigating in a QR code, right? I have not yet learned how to make a QR code, but somebody implemented a library for Common Lisp for that: cl-qrencode!

Let's use it!

(ql:quickload "cl-qrencode")

After running that, you will have this library available for hacking in the Slime's REPL! You can test the production of QR codes running the following code.

(cl-qrencode:encode-png "some text")

You should now have the path to the image that contains your text.

Now all that we are left with is to find the URL of the current page! Nyxt uses CLOS to implement things, which is Object Oriented Programming added to Common Lisp. That translates in buffers being objects. So a buffer owns functions and attributes! One of the attributes is the URL we are interested in!

So after navigating to a web page in Nyxt, you can get the Common Lisp URI of the page with the following.

(url (current-buffer))

This code accesses the attribute (or slot) url for the object returned by current-buffer.

This returns an URI object to make easier to query components like the domain or parameter list. We don't need this now, so we will get just the string. So the overall code is this.

(cl-qrencode:encode-png (quri:render-uri (url (current-buffer))))

This is all we need to make a QR code as a png for the URL of the current open page!

Here an image with my experimenting to show how fun it was.

/assets/blog/2021/06/29/extending-nyxt-via-emacs-how-to-leverage-common-lisp-wealth-to-get-your-links-as-qr-codes/screen-2021-06-29-19-13-01.jpg

Ah, and if you need a Nyxt command, this wraps our code.

(define-command-global my/make-current-url-qr-code ()
  "Something else."
  (when (equal (mode-name (current-buffer)) 'web-buffer))
  (cl-qrencode:encode-png (quri:render-uri (url (current-buffer))) :fpath "/tmp/qrcode.png"))

Finally, you can do all of this from Emacs!

(defun emacs-with-nyxt-make-qr-code-of-current-url ()
  "Open QR code of current url."
  (interactive)
  (if (file-exists-p "~/quicklisp/setup.lisp")
      (progn
        (unless (slime-connected-p) (emacs-with-nyxt-start-and-connect-to-nyxt))
        (emacs-with-nyxt-slime-repl-send-sexps
         '(ql:quickload "cl-qrencode")
         '(ql:quickload "cl-qrencode")
         '(cl-qrencode:encode-png (quri:render-uri (url (current-buffer))) :fpath "/tmp/qrcode.png"))
        (find-file "/tmp/qrcode.png")
        (auto-revert-mode))
    (error "You cannot use this until you have Quicklisp installed! Check how to do that at: https://www.quicklisp.org/beta/#installation")))

(I just added that to my repo.)

How easy was that?!? I cannot believe I waited so long to try. This is definitely the start of something amazing for me!

Conclusion

So refresh your Quicklisp and start integrating the amazing Common Lisp culture in Nyxt. If you have been following the other blogs I wrote about this, you should reproduce this pretty easily!

Happy QR-coding!

Comments