Posts

Migrating to a custom-file-less setup

I love the advocacy for a custom-less setup given here. Mind you, I have no desire to go without the customization family of helper commands like customize-group and customize-variable: the ability to rapidly explore the options available for plugins, libraries, and styles feels like a “killer feature”. But as software engineering has grown over the decades we are in a place to better understand the values in locating those customization in the same place where they can be associated, shared, and simultaneously deleted/edited.

Websockets for Clojure Sente in Apache Reverse Proxy

The Clojure library sente allows you to do smooth web-socket work in Clojure. In our case, we wanted the typical “Your Session Expires in N seconds” alert for users of the app. Sente was working smoothly on our local machines, but we were getting obscure errors in the console about 500 responses in our browser console. The Problem As mentioned, our console was showing server errors on the path that was supposed to be doing the Sente channels.

Capturing key-presses in Clojurescript with Closure

Having good keybindings on your site makes a world of difference for technical users (Twitter and Slack are good examples of this), but writing them yourself has several annoying steps. You have everything you need out of the box with Google Closure, though. Here’s how it goes withotu needing to add any dependencies to your project, since Closure is part of Clojurescript. Strategy and Solution The plan is simple:

zero-padding and truncating with string formats in Clojurescript

One of the discrepancies between Clojure and Clojurescript is that the javascript version doesn’t have anything like the classic Unix/C-style string format functions. Some functionality is not simply reproducible with clever uses of str, but fortunately Google Closure is here to save the day. Because Closure is part of Clojurescript, there are no added project dependencies to make this work. (ns myapp.services (:require [goog.string :as gstring] [goog.string.format])) (str "$" (gstring/format "%.

Major Java-interop in Clojure

This project was for a class in which we submitted java. I wrote this Clojure code to produce a Java class that could be run according to their specifications. So here is some of the first Clojure I ever wrote, long ago in grad school, utilizing the OpenCV system for computer vision. Notice the heavy use of obscure (non-Clojurey) APIs on objexts, marked by all the (.XYZ ...) lines. (ns com.

Emacs in Emacs: A triumph for EXWM

Previously I’ve talked about the inability to refer to my code screens from within exwm if I’m on a video call in my browser; it shows the option fo other browser windows, and the option of the whole screen, but not an emacs buffer. The solution is simple and beautifully recursive: run emacs within your exwm emacs. Do what? Run emacs within your main exwm emacs session. M-S & emacs.

How to send an interrupt without C-c C-c?

Using exwm with emacs-in-emacs I sometimes make a mistake and start a shell-process going that I need to stop. However, C-c is grabbed by my parent exwm session and so doesn’t send anything to my shell. How can I do this manually? Answer C-c C-c is short for comint-interrupt-subjob Resources https://www.reddit.com/r/emacs/comments/ja97xs/weekly_tipstricketc_thread/g8xu647?utm_source=share&utm_medium=web2x&context=3

Clojure exercise to transpose three lists

The need: take multiple vectors and view each vector as a column (not a row) of the data, so all the first items go together, all the second, etc. Here’s a rough version that felt too clunky (alert: it features a number) and fragile but happens to demonstrate the needs: (let [[names jobs langs :as all] [["john" "jane" "michael"] ["chef" "driver" "vet"] ["English" "German" "French"]]] (map #(zipmap [:name :job :lang] %) (partition 3 (interleave names jobs langs)))) ;; ({:name "john", :job "chef", :lang "English"} ;; {:name "jane", :job "driver", :lang "German"} ;; {:name "michael", :job "vet", :lang "French"}) Solution (let [[names jobs langs :as all] [["john" "jane" "michael"] ["chef" "driver" "vet"] ["English" "German" "French"]]] (apply map #(zipmap [:name :job :lang] %&) all)) ;; => ({:name "john", :job "chef", :lang "English"} {:name "jane", :job "driver", :lang "German"} {:name "michael", :job "vet", :lang "French"}) This solution taught me two new things:

Love lost: when exwm falls short

I find myself going back to regular WMs (my favorite from the past being KDE) because certain tasks are just deeply punishing in EXWM. When I’m doing my regular daily work I can usually make EXWM work for me. But here are the facts I experience with/without emacs as my window manager. Life is worse without EXWM Winum. Looking at a screen and hitting the num to focus there; I miss it dearly and cringe when I need to reach for the mouse.

Rebinding Keys, or, The Horror of Alt+TAB in Emacs

I use exwm so M-TAB is available to me without being hijacked by the OS, but rebinding this failed in surprising places. I want it globally to be set to iflipb-next-buffer (giving familiar alt+tab functionality to exwm), but if any of the buffers I’m travelling past happen to inherit magit or gnus, my tab-sequence gets broken because they have it bound to their own thing and I can’t seem to rebind it.