RSSAmplifier

Blog

Nicolas Martyanoff – Brain dump

Brain dump

n16f.netRSS feed ↗44 posts

Latest posts

Concurrency, interactivity, mutability, choose two

You have a Common Lisp program running, multiple threads listening for network connections, others processing data in the background. You were really careful making sure that there are no data access conflicts. Concurrency, check. You use Emacs and SLIME to connect to your server, inspect its state. Interactivity, check. You realize a global hash table contains an incorrect value; no problem, just…

Working with Common Lisp pathnames

Common Lisp pathnames, used to represent file paths, have the reputation of being hard to work with. This article aims to change this unfair reputation while highlighting the occasional quirks along the way. Filenames and file paths The distinction between filename and file paths is not always obvious. On POSIX systems, the filename is the name of the file, while a file path represents its…

Controlling link opening in Emacs

Multiple Emacs modes recognize URIs so that you can follow them in a web browser, usually with a mouse left click. In modes that do not support it, one can still call browse-url-at-point interactively with the cursor positioned on a URI. I wanted to make link handling more convenient for some time; this is what I ended up with. Key bindings There is no global Emacs concept of following links, so…

Taking control of your Go module paths

The canonical name of a Go module is its path. For third party modules, that means an URI. It is no secret that GitHub is currently the dominant code hosting platform, hence the fact that most Go modules are named github.com/<account>/<repository> . While I currently use GitHub for most of my repositories, I also want the ability to move out of it in the future. Fortunately the Go module system…

Pagination for database objects

So you have a server storing objects in a relational database, and an API, nowadays probably HTTP but it does not matter. Clients can fetch objects using the API. Obviously you do not want them loading too many objects at the same time, that would cause all kinds of performance issues. So you need a way to let clients request a manageable subset of all objects and iterate to finally obtain all…

Interactive Common Lisp development

Common Lisp programming is often presented as &ldquo;interactive&rdquo;. In most languages, modifications to your program are applied by recompiling it and restarting it. In contrast, Common Lisp lets you incrementally modify your program while it is running. While this approach is convenient, especially for exploratory programming, it also means that the state of your program during execution…

Building Erlang applications the hard way

Edit (2023-06-19) Updated to mention the +Bd option. I was recently in a conversation involving Erlang , and it made me feel like revisiting the subject. Last time I used Erlang for a commercial application, I remember a lot of frustration with the tooling, due in part to the small size of the ecosystem. Today I decided to read the documentation and see how to build an Erlang program from scratch.…

Reduce vs fold in Common Lisp

Introduction If you have already used functional languages, you are probably familiar with fold, a high order function used to iterate on a collection of values to combine them and return a result. You may be surprised that Common Lisp does not have a fold function, but provides REDUCE which works a bit differently. Let us see how they differ. Understanding REDUCE In its simplest form, REDUCE…

Replacing Ngrok with Frp

I have been using Ngrok for almost two years in order to test webhooks during development. It works really well, true; but even the personal plan costs $96 a year if you want a fixed URI. I recently came across Frp , a reverse proxy packed with useful features. This is how I used it to replace Ngrok entirely. Of course you will need a server running somewhere. It does not have to be powerful, even…

Making IELM More Comfortable

IELM is the Emacs Lisp REPL. It lets you evaluate any Elisp expression, prints the output and keeps track of previous commands. While it is a serious step-up from the humble eval-expression , it can be uncomfortable on several aspects. Let us improve it. Adding Eldoc hints Eldoc is a generic module used to display realtime documentation hints while you type. For Emacs Lisp, it means displaying…

Golang workspaces, at last!

Workspaces are a feature introduced in March 2022 with Go 1.18. They did not really get a lot of publicity, and I have not had the chance to experiment with them until recently. However I am really glad I did because they improve a major aspect of my workflow: dealing with multiple modules. Go modules are not ideal Go modules were a big help when they were introduced in 2018, but they were always…

Counting lines with Common Lisp

A good line counting program has two features: it only counts non-empty lines to get a fair estimate of the size of a project, and it groups line counts by file type to help see immediately which languages are used. A long time ago I got frustrated with two well known line counters. Sloccount spits out multiple strange Perl warnings about locales, and most of the output is a copyright notice and…

When your product idea has no market

At the end of 2021 I quitted my job to create a company with an ex-colleague. It did not work out. One year later, both the first and the second product were a failure, my business partner had quit to create a VC-funded startup, and I was left to pick up the pieces. Not fun. Since then I have been trying to find a new product to build while looking for contract work. This is a summary of my…

Gmail backups using ISync

Like so many people, I use Gmail. There are not a lot of options, and Google Workspace provides me additional useful services and lets me use my own domain name. However there has been a lot of horror stories about users losing access to their Gmail account without any recourse. It is not clear if it can happen with Google Workspace, but the risk is too high to ignore. I already backup my…

Custom Font Lock configuration in Emacs

Font Lock is the builtin Emacs minor mode used to highlight textual elements in buffers. Major modes usually configure it to detect various syntaxic constructions and attach faces to them. The reason I ended up deep into Font Lock is because I was not satisfied with the way it is configured for lisp-mode , the major mode used for both Common Lisp and Emacs Lisp code. This forced me to get…

Common Lisp implementations in 2023

Much has been written on Common Lisp; there is rarely one year without someone proclaming the death of the language and how nobody uses it anymore. And yet it is still here, so something must have been done right. Common Lisp is not a software, it is a language described by the ANSI INCITS 226-1994 standard; there are multiple implementations available, something often used as argument for how…

Reading files faster in Common Lisp

While Common Lisp has functions to open, read and write files, none of them takes care of reading and returning the entire content. This is something that I do very regularly, so it made sense to add such a function to Tungsten . It turned out to be a bit more complicated than expected. A simple but incorrect implementation The simplest implementation relies on the FILE-LENGTH function which…

Templating in Emacs with Tempo

I have used text editors for more than 20 years; in all that time, I have never used a templating system to generate content because copy pasting and replacing always felt good enough. I recently decided to give it a try. In Emacs it is hard to talk about templating without mentionning YASnippet . Developped by the prolific João Távora, who also developped Eglot , YASnippet lets you write…

Decluttering Dired for peace of mind

Dired is an Emacs mode providing an interactive interface to navigate and manipulate files. It took me a while to start using it, but it is so efficient that I now spend more time in it than in my usual shell. However I am no fond of the way files are listed. Dired displays a lot of information which is — at least for me — rarely used. As a result the important content (the name of the file) is…

Using units in Emacs Calc

I was recently reminded of the ability of Emacs Calc to perform computations on values with units. Like so many Emacs features, it was on the list of the things I wanted to explore. Today is the day to do so! Basic operations with units The Emacs Calc manual presents a lot of features but makes it hard to understand how to start. You cannot just enter an expression such as &ldquo;25mm&rdquo; in…

Custom Common Lisp indentation in Emacs

While SLIME is most of the time able to indent Common Lisp correctly, it will sometimes trip on custom forms. Let us see how we can customize indentation. In the process of writing my PostgreSQL client in Common Lisp, I wrote a READ-MESSAGE-CASE macro which reads a message from a stream and execute code depending on the type of the message: (defmacro read-message-case ((message stream) &rest…

Taking code screenshots in Emacs

My friend Rémi found an Emacs package developed by Tecosaur to take screenshots of your code. I usually do it with scrot , but it always requires spending some time cropping the result with Gimp. A bit annoying. Installation Let us give it a try. The screenshot package is not available on MELPA due to cosmetic issues , so we have two options. The first one would be to clone the repository , add…

ANSI color rendering in SLIME

I was working on the terminal output for a Common Lisp logger, and I realized that SLIME does not interpret ANSI escape sequences. This is not the end of the world, but having at least colors would be nice. Fortunately there is a library to do just that. First let us install the package, here using use-package and straight.el . (use-package slime-repl-ansi-color :straight t) While in theory we are…

Switching between implementations with SLIME

While I mostly use SBCL for Common Lisp development, I regularly switch to CCL or even ECL to run tests. This is how I do it with SLIME . Starting implementations SLIME lets you configure multiple implementations using the slime-lisp-implementations setting. In my case: (setq slime-lisp-implementations '((sbcl ("/usr/bin/sbcl" "--dynamic-space-size" "2048")) (ccl ("/usr/bin/ccl")) (ecl…

Improving Git diffs for Lisp

All my code is stored in various Git repositories. When Git formats a diff between two objects, it generates a list of hunks, or groups of changes. Each hunk can be displayed with a title which is automatically extracted. Git ships with support for multiple languages, but Lisp dialects are not part of it. Fortunately Git lets users configure their own extraction. The first step is to identify the…

Eshell key bindings and completion

I have been having completion issues in Eshell for some time, and I decided to fix it. Of course the yak shaving is always strong with Emacs, so it ended up being a bit more complicated than expected. Defining keys with use-package Eshell key bindings are stored in eshell-mode-map . For quite some time, Eshell has been initializing this value to nil , making it impossible to define keys before…

Org-mode headline tips

Org-mode is what got me into Emacs in the first place. I use it to take notes, keep track of what I have to do and plan projects. An Org file is a tree of elements, each one starting with a headline. Manipulating headlines can be confusing; here are a few tips that you may find helpful. Do not split lines when adding headlines At any point, you can insert a new headline below the current one using…

Configuring SLIME cross-referencing

The SLIME Emacs package for Common Lisp supports cross-referencing: one can list all references pointing to a symbol, move through this list and jump to the source code of each reference. Removing automatic reference jumps While cross-referencing is very useful, the default configuration is frustrating: moving through the list in the Emacs buffer triggers the jump to the reference under the…

Replacing Projectile by Project

I have been using Projectile for years, and it served me well. While Projectile is really useful, it is a third party package made of more than 8000 lines of code. Since the built-in Project module has received lots of improvements since Emacs 28.1, I decided to give it a try and see if I could remove Projectile from my Emacs setup. Key binding The Project keymap is bound to C-x p by default, but…

Clearing the Eshell Buffer

I have used the C-l shortcut in ZSH to clear the screen for as long as I can remember. When I started using Eshell , one of the first problems I encountered was the inability to clear the buffer. I like to remove the output of previous commands to be able to focus on the current one, so let us script Emacs once again. After a quick look to the eshell module, it seems we can do that in two steps:…

Investigating a FFAP issue in Emacs

I just encountered the strangest behaviour in Emacs. I was editing a shell script, hit C-x b to switch to another buffer, and Emacs suddenly froze with the following message: Pinging <hostname> (Commercial)... Where <hostname was the hostname of a server used in the script. I really do not like the idea of my text editor pinging random servers just because their name appears in a buffer, so I went…

Fixing unquote-splicing behaviour with Paredit

Paredit is an Emacs package for structural editing. It is particularly useful in Lisp languages to manipulate expressions instead of just characters. One of the numerous little features of Paredit is the automatic insertion of a space character before a delimiting pair. For example, if you are typing (length , typing ( will have Paredit automatically insert a space character before the opening…

SLIME compilation tips

I recently went back to Common Lisp to solve the daily problems of the Advent of Code . Of course it started with installing and configuring SLIME , the main major mode used for Common Lisp development in Emacs. The most useful feature of SLIME is the ability to load sections of code into the Common Lisp implementation currently running. One can use C-c C-c to evaluate the current top-level form,…

Eye level window centering in Emacs

In the default Emacs configuration, C-l is bound to recenter-top-bottom . This function has an interesting behaviour: when called once, it scrolls the current window so that the current line appears at the middle of the screen. When called several times in a row, it cycles through three scrolling position: middle, top and bottom. This has always bugged me because I only need one of the three…

Exporting 1Password data for backup

Storing credentials and confidential data in a secure location is important, and I have been happy with 1Password for years. But having all this critical information stored in a single location is dangerous; losing access to my 1Password account would be quite annoying, forcing me to reinitialize passwords on dozens of websites and making me lose a lot of information. Fortunately it is possible to…

Using GnuPG

Edit (2023-02-07) Updated to mention subkey selection during renewal. Introduction I recently tried to learn more about GnuPG and it turned out to be more difficult than expected. So here are my notes regarding various GnuPG operations. GnuPG 2.2.32 was used for all commands. Configuration GnuPG The gpg command line tool looks for $HOME/.gnupg/gpg.conf . Options are provided using the command line…

Default configuration for the Erlang logger

The Erlang logger application introduced in OTP 21 is extremely flexible, but the default settings are not the most practical for development purposes: The default log level is notice , meaning that info and debug messages will not be printed. Log messages with a domain other than [otp] will not be printed. Each printed log message will start with a cumbersome banner, e.g. =NOTICE REPORT====…

Unknown type specifications with Dialyzer

I use Dialyzer a lot, and it has always been useful to expose various errors in my Erlang code. Unfortunately, I recently discovered an unexpected behaviour: by default, Dialyzer ignores unknown types. It is very surprising and suddently makes me doubt any piece of Erlang code I ever wrote. As it turns out, there is a Dialyzer flag to detect and report these unknown types. With Rebar3 , it can be…

Local CLHS access in Emacs

The CLHS, or Common Lisp HyperSpec, is one of the most important resource for any Common Lisp developer. It is derived from the official Common Lisp standard, and contains documentation for every aspect of the language. While it is currently made available online by LispWorks , it can be useful to be able to access it locally, for example when you do not have any internet connection available. For…

ASDF in Common Lisp scripts

The usual way to develop programs in Common Lisp is to use SLIME in Emacs, which starts an implementation and provides a REPL. When a program needs to be running in production, one can either execute it from source or compile it to an executable core, for example with sb-ext:save-lisp-and-die in SBCL. While executable cores works well for conventional applications, they are less suitable for small…

Persistent history for the Erlang shell

While the erl application is really useful to tinker with Erlang modules, the lack of a persistent history has always been annoying. I recently discovered via Adopting Erlang that the history can be made persistent since Erlang 20 with specific flags, which can be added to the ERL_AFLAGS environment variable to have them enabled by default. Shell history is handled by the group_history module;…

Reading RFC documents in Emacs

I am used to read RFC documents in Emacs by opening them as simple text files. But I was always annoyed by the impossibility to follow references to other documents. Additionally, searching for the right RFC usually involve going back to the web browser and Google while I would prefer staying in Emacs. Since I enjoy Helm so much, I thought it would be easy to parse the index of all RFC documents,…

Printing non-ascii characters in Erlang releases

I have been learning a lot about Erlang recently, and I stumbled upon a strange behaviour: printing strings containing non-ascii characters, e.g. "μs" , using io:format and the ~ts control sequence behaves differently depending on the way the program is run: In rebar3 shell , rebar3 run , or a release running with a console: "μs" . With a release running in foreground: "\x{3BC}s" . I first checked…

Buffer ordering with Helm

I have been using Emacs for some time, and ido has always been my favourite way to switch buffers. But recently I discovered and started using Helm , a package based on incremental completion which can provide lots of interesting features. One of them being buffer switching. The simplest way to use Helm to switch buffers is helm-buffers-list . Personally I use C-x b : (global-set-key (kbd "C-x b")…