Sep
23
2024

Ymacs: Twig/Django mode and other news

As I find myself writing code in Ymacs sometimes, I wrote a mode suitable for editing Twig/Django templates. It can be enabled with M-x twig_html_mode (the dogfood init code will auto-enable it for buffers coming from web-mode if the filename contains .twig).

While working on this (in itself, of course) I fixed a bunch of other issues related to indentation and syntax highlighting. JS mode will now highlight class, method and function names, and given these changes, I'd like to start working on some imenu-like functionality. Although, to be honest, the current “parsing” system could best be described as “a mess that works”, even after the significant refactoring at the beginning of this year (2024). My efforts would probably be better spent adopting CodeMirror's excellent parser generator (Lezer). But oh well, for now stuff is good enough. 🥲

Here's a small demo with the new Twig mode on:

[ read more... ]


May
31
2024

Carriage return in SLIME output

Here is a small Emacs/SLIME tip, since I couldn't find it on Google and I had to come up with the solution myself. I'm working on a long running Common Lisp program and I print a dot every few thousand iterations, so that I know that something is happening; then every few hundred of thousands I want to replace those dots with some stats about the computation, so I'm writing a carriage return (char code 13) and the stats. On a normal terminal, the whole line of dots will be replaced by the new output, but Emacs just prints ^M and adds the stats on the same line.

Although SLIME seems to be derived from Comint mode, it doesn't use the same code for output (Comint already handles a bunch of caret movement codes, including CR). To make it work in SLIME, paste the following somewhere in your Emacs config (it probably needs SLIME to be already loaded for the advice to work; it is loaded in my case):

;; Interpret #\Return in SLIME output (carriage-return)
(defun my-slime-fix-output (orig-fun &rest args)
  (with-current-buffer (slime-output-buffer)
    (ignore-errors
     (let ((pos (marker-position slime-output-end)))
       (apply orig-fun args)
       (comint-carriage-motion pos (marker-position slime-output-end))))))

(advice-add 'slime-repl-emit :around 'my-slime-fix-output)

May
8
2024

Dogfooding Ymacs

I first learned the term dogfooding at Zimbra in 2005, where we were using the email server and client that we were developing. The internal domain name was dogfood.zimbra.com.

Why would I want to use Ymacs? Its purpose was to enable me to write code in a browser, but in the comfort of my desktop, I can use the real thing. And indeed, Emacs is almost irreplaceable, because it's not just about the editor itself, but the immense ecosystem around it. How can one program in an editor without Magit, for example?

But there are reasons. First, to me, there's this pleasure of using a tool that I created. Then, I'm a strong believer in manual testing — the only way to ensure it's reasonably stable is to actually use it (yes, I'm typing in Ymacs right now). Then, some things might even be better than in Emacs, depending on case and setup — for example I noticed that Emacs with js2-mode (that's what I use) will mismatch quotes of nested template strings. That works properly in Ymacs (including indentation in nested expressions).

I thought that if I could quickly switch between the two, I could use Ymacs for editing work, and go to Emacs for anything else, like Magit. Thus came the idea of a dogfood server — Ymacs would connect to a running Emacs instance, and provide a way to load/save buffers via Emacs. That was pretty easy to write. Yes of course there is a HTTP server for Emacs.

[ read more... ]


Apr
19
2024

Ymacs Reloaded

Hello. Here's an Ymacs update, after 12 years. Remember Ymacs? It's an Emacs-like editor that works in the browser. Here is what's new.

  • Zero dependencies. Ymacs no longer requires my old DynarchLIB toolkit. The minified and gzipped payload is under 50K, which is pretty small by today standards. Along with this change I modernized the code to use ES6 features (e.g. classes, modules), improved theming and added a simple build system based on Parcel.

  • Improved isearch, query-replace. This took a surprising amount of fiddling, but finally, it's Good™. It has “lazy highlighting”, stats (current/count), regexp, word, case folding, lax whitespace. Query-replace is new (old Ymacs didn't have it). Supports similar-case in replacements, regexp replacement variables, bound to selection when active, etc. — with the standard Emacs keybindings, except for C-w 😢 which see below.

[ read more... ]


Aug
15
2023

Get image dimensions (PNG/JPG) without loading the file in Common Lisp

Hey Common Lispers! Why are we so few, when this language, and tooling, is so amazing and fabulous? :)

Today I added PhotoSwipe on a website I'm working on for a friend. The backend is written in Common Lisp, because life's too short. PhotoSwipe is a wonderful library, It Just Works™, but it has this minor-yet-inconvenient requirement — you have to declare the image size (width and height) for each thumbnail, in some data attributes. I've searched for some Common Lisp code that could fetch an image dimensions from the file, and I couldn't find any. There are image manipulation libraries, alright, but they parse and decode the whole file (and that's slow), when I only need the dimensions. Those could be fetched from the headers, reading just a few bytes and consing nothing at all (or almost nothing).

Following research, since I couldn't find any code that does that, I wrote my own. I hope it will be useful for someone else too. Pasting it below, or get it from this GitHub gist. It should work okay for PNG, JPEG and GIF. I'm not so sure about WEBP. Any comments or improvements are welcome!

Update: I added a proper parser to figure out orientation from the Exif block (which is really a TIFF header).

[ read more... ]


Oct
21
2022

Always choose simple

Today I was tasked with something rather trivial at work, and I wrote the simplest, dumbest code possible to solve the problem. A colleague of mine was surprised looking at my patch, she said it's so simple and beautiful, as she expected some more involved cleanup or refactoring. This brought to mind a little story I'd like to share.

[ read more... ]


Jun
30
2021

No hover please

Ever watch videos online? Ha ha, of course you do. Now here's what bothers me. I set the video — for example eurosportplayer.com — in full-screen, on a desktop, but I don't really watch continuously, I let it play and come back to it every now and then. Whenever I switch back to that desktop, a gross overlay with the video controls shadows the media for like 5 seconds. Even the slightest mouse movement brings on that despicable thing.

If this is pissing you off too, and if you are using Linux + Xorg/X11, then I have a solution. It's called nohoverplease but feel free to name it whatever you like, like fuckyouroverlay or something. It's an empty and fully transparent window that does nothing at all, it just sits there, maximized, on top of the browser, and won't let it know it's visible or catch mouse movements, so the damn overlay won't show up. I do have bigger problems in life, but it feels good to solve at least the little ones.

[ read more... ]


May
15
2021

JavaScript Sudoku solver

My wife has developed a passion for Sudoku. I do not share it, I've always thought that this is a problem for computers, not humans, so I've never tried to solve one by hand. However, even if it's a high school problem, I thought it'd be a cute little program to work on. This is the obligatory blog post about it.

Update: see bestest version.

[ read more... ]


May
9
2021

New server

“If you don't schedule time for maintenance, your equipment will schedule it for you”

So true! After almost ten years of continuous functioning, one of the hard drives failed and I was left with an unbootable server. Last time I checked it had more than five years uptime. I managed to backup, last minute, things that I should have backed up periodically, and I got a new server, also from Hetzner (whom I warmly recommend, without having any affiliation to them, other than the fact that they are my favorite host for the past 10 years or so).

Sysadmin work sucks. I only do it when the hard drive fails :) so that's about once every 10 years. Still, I was able to put back together my DNS server pretty quickly; also this website, because it's written in Common Lisp. 10 years old software, unchanged, compiled by bleeding edge SBCL running on bleeding edge Arch Linux; now that's stability.

Until the dust settles, comments will be disabled (missing a SMTP server for now). Permanent victims are my old Perl-based websites, including my old blog; I won't bother to get them back up, but there's the Internet Archive if you miss anything.

There'll be a new blog post soon, about Sudoku. I'm not dead yet. :)


Sep
6
2020

Corona US Open and other thoughts

Nice to finally see some live tennis after so long! The US Open has started. Some top players are missing — no Nadal, no Halep (they rather concentrate on Rolland Garros; understandably, since clay is their preferred surface); no Federer (some knee injury).

Some of the bad boys who had the coronavirus are playing, like Djokovic and Dimitrov. The latter just went out. But it was a good match, take a look at the highlights if you like tennis. How strange it feels to watch these intense points without hearing the crowds' murmur of amazement! There are no crowds, because... pandemic! These huge arenas are empty.

Of course, players don't wear a mask during play; on average, a match takes 2-3 hours — it would be impossible to put that effort with a mask. But after the match, the winner gives an interview and that's... with a mask on! Take a look at Sofia Kenin. She's alone, in the middle of the empty court, with the mask on. The interviewer is nowhere to be seen, she's probably not even there.

Is it player's choice to wear the mask here? I don't think so, she's already been all over the place for two hours without a mask. Most probably, these are the regulations, but what could be the purpose? Clearly there is no risk to get infected, nor to infect anyone, because there's no one around! The virus doesn't just fall from the sky; if it did there would be no tennis and we'd stay indoors and homo sapiens would end, which probably wouldn't be too bad.. but I digress. The only purpose that can be is to maintain fear.

The most heartbreaking change is that they are no longer allowed to shake hands. Most players known each other for years, they are friends and they remain friends even after a hard fight; they used to shake hands and hug at the end, which is really what friends do, but now they just tick rackets and that's it. Sad. Meanwhile in footbal:

You can see these images after every goal. Now, I get it, manifestation of joy is part of the game, is something human and it shouldn't be forbidden, but then why not allowing tennis players to shake hands at the end? It just doesn't make sense. Also, while restaurants reopened just days ago with very strict rules, here's our beloved football players:

No distancing, no masks, indoors. This is practically illegal. What I'm trying to say, I guess, is that nothing seems to make sense! I feel like something more sinister than just the virus is going on. I want and try hard not to believe in conspiracy theories, but I feel like some unseen hand is manipulating all of the press and all the governments, worldwide, silencing voices that try to sing a different kind of music.

I find it weird that the Bill and Melinda Gates Foundation is pouring money both into the WHO, which declared the pandemic and dictates the regulations worldwide, and in ID2020, which recognizes “the opportunity for immunization to serve as a platform for digital identity“, which pretty much means they'd like to use vaccines to insert RFID tags into us; and that the press is talking about how the pandemic will not end until a vaccine is available, which kind of implies that vaccination will be mandatory, and all of a sudden conspiracy theories seem to become reality, in your face! They don't even hide!

I'm not exactly “anti-vaxxer”, but I try to get informed and think, and it's not hard to connect these dots. I wouldn't like to get an ID chip inside my body, so I will refuse vaccination... if I can! I think that's the end goal of this “pandemic” — mandatory vaccination of the whole planet, and that could mean digitally stamping everyone. My cat has a chip, but I'm not a cat and I'd rather not have one.


« Before 6 Sep 2020