Emacs

The pages where I write about Emacs. It doesn’t happen very often. I think you’re probably best off following Planet Emacsen, the ultimate Emacs related blog aggregator.

2020-12-21 Manual autocrypt

I got encrypted mail, yay! I noticed that the sender had helpfully used autocrypt, because there was a header:

Autocrypt: addr=somebody@example.com; keydata=
 ABC...
 DEF...

How to extract this? I don’t know. I know that with Delta Chat, this would have just worked. I noticed that Emacs has a package implementing autocrypt, but I don’t actually want to setup an account and I don’t understand all the extras it does (gossip‽) – so I wanted to do it manually.

I saved the keydata in a file and decoded it, ignoring the whitespace at the beginning of each line:

base64 --ignore-garbage --decode test.txt > test.key

And imported it:

gpg --import test.key

Phew! 😅

Add Comment

2020-12-17 Rmail

January 2015 I decided I had enough. I downloaded all my mail from Gmail and deleted everything on the server. I kept using it however. I justed wanted a “clean email day”.

Over the years, I’ve started trying to keep the principles of data parsimony in mind:

  • don’t collect it
  • don’t store it
  • don’t keep it

Data is toxic. It’s a bit like being your own record keeper. You know the ones: the narcissists that keep records of every conversation you’ve ever held so that they can prove you wrong instead of treating you like a human being. That’s why I don’t want to keep it. I don’t want to treat others like this. If somebody has a bad day and sends me an angry email, I hope to delete it like all the other emails, and years later I won’t be able to find it anymore, I won’t remind myself of the words they said, I’ll hopefully be able to forgive, and I’m setting myself up to forget.

So, I stopped using the Gmail web client. Google the data kraken, Google the spearhead of surveilance capitalism. I don’t want to live in front of the camera with algorithms watching my every move, using the data they gather about me to manipulate me into voting for this or for that, or to buy this or that. “And lead us not into temptation, but deliver us from evil.” And remember, “Don’t be evil” was a part of Google’s Code of Conduct from 2000 to 2018. They removed it.

Currently, I’m using Migadu as my email provider. For a while I tried to use Gnus (which is part of Emacs) to read mail, with the IMAP backend. Sadly I ran into problems with disappearing mail and had to stop. I was a big Gnus fan back in the days. Time to let go. I also tried using aerc and that works pretty well. It’s not super easy to setup with Emacs but it works. Except it crashes when I get encrypted mail, and that’s not good. And in order to build it from source, I need a new Go development environment. The one that comes with my distro is not good enough. How annoying. So I’ve been using Evolution, particularly when using encrypted mail. But these graphical user interfaces drive me nuts. Tiny target areas to click a gazillion times to get anything done. Aggravating!

Recently, @cadadr wrote a blog post explaining his Rmail setup. Rmail is this stupid simple mbox based mail client. I used it for a tiny bit as I got into Emacs back in the nineties before moving on to Gnus. A few years later, I tried to make some changes to Rmail (back then it used the BABYL format which was similar but incompatible to the mbox format; and I wanted to add MIME handling). Anyway, I failed and abandoned the code. Yikes! I did not have good Rmail memories.

But Göktuğ’s blog post was like a siren song: I have good key bindings for Rmail, it said. You don’t need to fiddle with postfix or sendmail, it whispered. I can search your mails, it sang. I had to try it. And I loved his introduction: “This blog post instead is about how I deal with a humane level of email messaging, with a local-first approach, using a smallish variety of software, which you can just set up and forget about.” This is beautiful!

The result is part of my Emacs config files. I skipped the procmail setup. I made some other changes. But essentially, it’s the same thing. Instead of “pass” I’m using “gpg” to decrypt my email passwords (“passwordeval gpg --no-tty --quiet --decrypt ~/.config/mpop/password.gpg”). And slowly I’m adding more. Today I added code to move mails to a trash mbox instead of expunging it because today was the first time I got email with an important piece of information that I deleted before recognising later in the day that I needed it: and there was no mail trash to look at. It was simply gone. Eventually I shall write some code that expunges old mail from the trash file. I’m giving myself thiry days. 😆

Here’s what I use for working with aerc. It’s a new “eml-mode” allows me to use ‘C-c C-c’ to send email instead of having to use ‘C-x #’. That’s simply cumbersome to use and ‘C-c C-c’ is used everywhere else…

;; I use aerc to read mail and emacsclient as my mail editor
(server-start)

(define-derived-mode eml-mode mail-mode "Email"
  "Write emails via emacsclient."
  (when (buffer-file-name)
    (set (make-local-variable 'server-temp-file-regexp) ""))
  (local-set-key (kbd "C-c C-c") 'server-edit)
  (auto-fill-mode 1))

(add-to-list 'auto-mode-alist '("\\.eml\\'" . eml-mode))

And here’s the Rmail section where I set up the directories and files (the trash file is not standard). “mpop” delivers mail into the “inbox”, and Rmail then moves it from there into the “current” file. If I decide to keep it, I’ll move it into the “archive” file.

(setq rmail-primary-inbox-list '("/home/alex/mail/inbox"); where mail comes from, delivered by mpop
      rmail-file-name "/home/alex/mail/current"; where I read mail
      rmail-secondary-file-directory "/home/alex/mail"; where the other folders are
      rmail-secondary-file-regexp "spam\\|sent\\|archive$"; the interesting other folders
      rmail-default-file "/home/alex/mail/archive"; where mail I want to keep goes
      ;; I don't differentiate between spam and trash anymore because
      ;; I'm relying on my provider's spam filter. I'm not running a
      ;; local spam filter.
      rmail-trash-file "/home/alex/mail/trash")

I like the brutalist-dark theme, and have made some changes over there:

(custom-theme-set-faces
 'brutalist-dark
 '(message-header-cc ((t (:inherit bold))))
 '(message-header-name ((t (:inherit default))))
 '(message-header-newsgroup ((t (:inherit default))))
 '(message-header-other ((t (:inherit default))))
 '(message-header-subject ((t (:inherit bold))))
 '(message-header-to ((t (:inherit bold))))
 '(message-header-xheader ((t (:inherit default))))
 '(message-cited-text-1 ((t (:inherit default))))
 '(message-cited-text-2 ((t (:inherit default))))
 '(message-cited-text-3 ((t (:inherit default))))
 '(message-cited-text-4 ((t (:inherit default)))))

And I also needed to change one of these variables because unread mail was using font-lock-type-face, which is underlined in my programming setup. So I wanted something different. I decided to copy the whole assignment as I don’t want to load Rmail when I start Emacs and I was too lazy to write the eval-after-load invocation.

(defvar rmail-summary-font-lock-keywords
  '(("^.....D.*" . font-lock-string-face)			; Deleted.
    ("^.....-.*" . 'bold)				        ; Unread.
    ;; Neither of the below will be highlighted if either of the above are:
    ("^.....[^D-] \\(......\\)" 1 font-lock-keyword-face)	; Date.
    ("{ \\([^\n}]+\\) }" 1 font-lock-comment-face))		; Labels.
  "Additional expressions to highlight in Rmail Summary mode.")

Well, the joy was short because soon after there it is. The rmail-mode-map isn’t defined so if I want to change the key maps, I have to delay this.

(eval-after-load "rmail"
  '(progn
     (define-key rmail-mode-map "<" 'asc:fetch-mail)
     (define-key rmail-mode-map "A" 'asc:archive-mail)
     (define-key rmail-mode-map "d" 'asc:trash-mail)
     (define-key rmail-mode-map "$" 'asc:trash-mail)
     (define-key rmail-mode-map "S" 'mairix-search)
     (define-key rmail-mode-map (kbd "<tab>") 'asc:rmail-forward-link-or-button)
     (define-key rmail-mode-map (kbd "<backtab>") 'asc:rmail-backward-link-or-button)))

The same is true for Message mode, which is used to write mails.

(eval-after-load "message"
  '(progn
     (define-key message-mode-map (kbd "C-c C-c") 'message-send)))

And the summary buffer:

;; Redefining quit
(eval-after-load "rmailsum"
  '(progn
     (define-key rmail-summary-mode-map "q" 'bury-buffer)))

Global stuff is OK:

(global-set-key (kbd "C-c <") 'asc:fetch-mail)

Then some functions to fetch mail, and to move mail.

(defun asc:fetch-mail ()
  "Run mail retrieval scripts."
  (interactive)
  (make-process
   :name "fetch-mail" :buffer (get-buffer-create "*Fetch Mail*")
   :command (list "mpop" "-Q" "-a")
   :sentinel
   (lambda (process event)
     (unless (process-live-p process)
       (when (zerop (process-exit-status process))
         (if (> (file-attribute-size (file-attributes (car rmail-primary-inbox-list))) 0)
	     (message "New mail!")
	   (message "No new mail.")))))))

(defun asc:archive-mail ()
  "It will move the current message to ‘rmail-default-file’
This command will not run unless in an RMAIL buffer visiting
‘rmail-file-name’."
  (interactive)
  (unless (string= (buffer-file-name) rmail-file-name)
    (user-error
     "This is not your default RMAIL file"))
  (rmail-output rmail-default-file)
  (rmail-delete-forward))

(defun asc:trash-mail ()
  "It will move the current message to ‘rmail-trash-file’
If you're currently visiting the trash file, then it will be
deleted."
  (interactive)
  (unless (string= (buffer-file-name) rmail-trash-file)
    (rmail-output rmail-trash-file))
  (rmail-delete-forward))

I did not know about mairix, the tool used for searching mail. The way it is used is that you run a search and it writes a temporary mbox for you, which is then opened with Rmail. You’re basically reading a copy of the emails matching your search terms. I love this.

(setq mairix-file-path "/home/alex/mail/mairix"
      mairix-search-file "search")

(autoload 'mairix-search "mairix" "Call Mairix with SEARCH.")

Not sure I actually need these. Stuff to navigate not just to the buttons (to hide and show the various parts in multipart emails) but also to the links.

(require 'cl-lib)

(defun asc:rmail-forward-link-or-button (p)
  "Navigate both links and buttons in Rmail in a ring.
This replaces the use of ‘forward-button’ which only traverses
buttons and skips over links."
  (interactive (list (point)))
  (let (positions)
    (dolist (overlay (overlays-in (point-min) (point-max)))
      (when (memq (car (overlay-properties overlay))
                  '(goto-address button))
        (pushnew (overlay-start overlay) positions)))
    (setq positions (sort positions #'<))
    (if (>= p (car (last positions)))
        (goto-char (first positions))
      (goto-char (find-if (lambda (x) (> x p)) positions)))))

(defun asc:rmail-backward-link-or-button (p)
  "Navigate both links and buttons in Rmail in a ring.
This replaces the use of ‘forward-button’ which only traverses
buttons and skips over links.
This is the reverse counterpart of
‘gk-rmail-forward-link-or-button’."
  (interactive (list (point)))
  (let (positions)
    (dolist (overlay (overlays-in (point-min) (point-max)))
      (when (memq (car (overlay-properties overlay))
                  '(goto-address button))
        (pushnew (overlay-start overlay) positions)))
    (setq positions (sort positions #'<))
    (if (<= p (first positions))
        (goto-char (car (last positions)))
      (goto-char (find-if (lambda (x) (< x p)) positions :from-end t)))))

And here’s sending mail. We need the FCC header to keep a copy of the mails we send. It’s yet another mbox file. Easy! And I want to hide the “In-Reply-To” header.

(setq message-send-mail-function 'message-send-mail-with-sendmail
      message-sendmail-f-is-evil t
      message-sendmail-envelope-from 'header
      sendmail-program "msmtp"
      message-default-headers "Fcc: /home/alex/mail/sent"
      message-auto-save-directory "/home/alex/mail/drafts"
      message-confirm-send t
      message-hidden-headers '("^References:" "^X-Draft-From:" "^In-Reply-To:"))

(add-hook 'message-sent-hook 'bury-buffer)

Receiving mail uses mpop (meaning that the mails are also removed from the server!) and sending mail uses msmtp. None of that complex local mail infrastructure setup, as I said. Those things you can leave like your distro set them up, locally. Don’t touch them! I like it.

As for the setup of mpop and msmtp, I use the following for “~/.config/mpop/config”:

defaults
tls on
tls_starttls off
keep off
password
account default
host pop.migadu.com
port 995
user alex@alexschroeder.ch
delivery mbox "/home/alex/mail/inbox"
passwordeval gpg --no-tty --quiet --decrypt ~/.config/mpop/password.gpg

Note the “password.gpg” file containing nothing but the mail password, encrypted for my GPG key.

And this is “~/.config/msmtp/config”:

defaults
auth on
tls on
tls_starttls off
protocol smtp
password
account default
host smtp.migadu.com
port 465
from alex@alexschroeder.ch
user alex@alexschroeder.ch
passwordeval gpg --no-tty --quiet --decrypt ~/.config/mpop/password.gpg

Anyway, thanks again, Göktuğ. 😃

Comments on 2020-12-17 Rmail

Hi! Glad it was useful to you!!

– Göktuğ “the other guy who uses Rmail” Kayaalp 2020-12-19 18:08 UTC


Actually Using Emacs Rmail, by Muto.

– Alex 2021-04-03 22:37 UTC


In my ~/mail directory I have a Makefile with the following:

all:
	mail-expire 30 archive sent
	mail-expire --delete 30 trash

The mail-expire tool will take all the mails older than 30 days from the archive and sent files and move them to timestamped files such as archive.Mar_2021.gz and sent.Mar_2021.gz (I hate the naming convention and might have to change that, haha!), and it deletes all messages older than 30 days from trash.

– Alex 2021-04-10 06:40 UTC

Add Comment

2020-10-23 The finger memory of incremental search, or switching to swiper

I’ve used C-s and C-r to search in Emacs for ages. One of the most used combos was to move somewhere, start incremenental search, and yank some words from the current position in the buffer: M-b M-b C-s C-w C-w C-s. Now I’m trying to give Swiper a fair try. I’ve been using Yvy Mode until now but I never went all the way.

Recently, however, I stumbled upon the Swiper repository, which comes with a README that has a sample rebinding of keys for all the Ivy, Counsel and Swiper stuff. One of them was to use C-s for swiper-isearch instead of isearch-forward. OK! I’m going to try it.

Note that swiper-isearch is not line-based like swiper is. That is, <down> goes to the next match, even if the next match is on the same line.

But… my fingers are all confused, now. I need to switch modifier keys: M-b M-b C-s M-j M-j <down>. Perhaps I should start using M-s instead. But then again, that prefix hides a ton of functionality. But then again, I never use it.

This is what Emacs Paralysis looks like, I’m telling you!

Anyway, once you started your search for the current word using C-s M-j you can use C-c C-o to switch to Yvy Occur mode. From there, you can use w or C-c C-p to switch to Wgrep mode, which allows you to make changes to the buffer and to write them back to the files using C-x C-s. Strangely enough this doesn’t work if you’re using it in a buffer that has no file associated with it! How strange. This must be an unintended consequence of the grep heritage.

In any case, I’m still trying to get used to this. And I’ll give iedit a try as well. I’m hoping for some sort of refactoring support in Emacs.

All of these idea are from @takeonrules’s blog post:

Add Comment

2020-08-26 Emacs without the bling

On Mastodon, @pet84rik posted a link to Emacs, naked., by @bzg. I compared it to my own setup and found that I use many of the same things.

;; deactivate some bling
(dolist (mode '(tool-bar-mode
		blink-cursor-mode
		menu-bar-mode
		scroll-bar-mode))
  (when (fboundp mode)
    (funcall mode -1)))

You can find code like this and similar stuff in my Emacs config, which is a lot better organized than it used to be.

Screenshot

When I scrolled down, however, I noticed something else: Bastien hides the mode-line completely. I’m using @algernon’s Brutalist Dark theme, which has visible mode-lines but the inactive mode-line is not readable (foreground and background colour are the same). It’s less distracting. Still, I started wondering.

With minor tweaks, I added the following:

(defvar-local hide-mode-line nil)

(define-minor-mode hidden-mode-line-mode
  "Minor mode to hide the mode-line in the current buffer."
  :init-value nil
  :global nil
  :group 'editing-basics
  (if hidden-mode-line-mode
      (setq hide-mode-line mode-line-format
            mode-line-format nil)
    (setq mode-line-format hide-mode-line
          hide-mode-line nil))
  (force-mode-line-update)
  ;; Apparently force-mode-line-update is not always enough to
  ;; redisplay the mode-line
  (redraw-display)
  (when (and (called-interactively-p 'interactive)
             hidden-mode-line-mode)
    (run-with-idle-timer
     0 nil 'message
     (concat "Hidden Mode Line Mode enabled.  "
             "Use M-x hidden-mode-line-mode to make the mode-line appear."))))

;; Activate hidden-mode-line-mode
(hidden-mode-line-mode 1)

;; Hide the mode-line in all new buffers
(add-hook 'after-change-major-mode-hook 'hidden-mode-line-mode)

;; Use F12 to toggle modelines
(global-set-key (kbd "<f12>") 'hidden-mode-line-mode)

I’m liking it! And when I occasionally want to see something – mostly the column I’m at while I’m writing the first line of a git commit message – I can quickly use F12 to see it.

I remember in the old days I needed the mode-line to track IRC activity. These days, however, with me being connected to a bunch of Discord channels that I never read, and a bunch of Mastodon accounts, all via Bitlbee, the actual mode-line is far less useful than it used to be.

Screenshot

I continued scrolling down on Bastien’s page and saw the centred Emacs window (using the fringes). This would actually work very well for me, since I always use Emacs in full-screen mode. I recommend it! But if you’re not a big user of C-x 3 to split the window into two side-by-side windows, then all your text is going to on the left side of your monitor. Not good! Not good.

So here we go:

;; center the window by adding a very wide fringe
(define-minor-mode center-window-mode
  "Minor mode to center the window using wide fringes."
  :init-value nil
  :global t
  :group 'editing-basics
  (if (not center-window-mode)
      (set-fringe-style nil);; default
    (set-fringe-mode
     (/ (- (frame-pixel-width)
           (* (+ fill-column 4)
	      (frame-char-width)))
        2))))

(center-window-mode 1)

;; Use F9 to toggle centering
(global-set-key (kbd "<f9>") 'center-window-mode)

This uses the fill-column to calculate the width of the fringes. If you’re suddenly in a buffer with a different fill-column, just use F9 F9 to toggle it off and on again, and the new fill-column value is taken into account.

I’m sure this could be smarter, but it basically works for me. When I’m programming, I often use up to 120 characters per line; the fill-column only affects comments. I therefore leave it where it is and just toggle the centring of the window. The font-size I prefer to use and the width of my laptop screen give me about 125 characters per line max. Those two or three characters don’t make a big difference in the left margin, so I don’t really need code to do <f9> C-u 120 C-x f <f9> – I tried it and it wasn’t worth it.

So here we are.

Screenshot

Actually, let me get back to the window splitting issue again. I started talking with @ckeen and I think my main problem with Emacs is that it’s hard to keep the window configuration stable. As soon as you start using help, man pages, IRC, and the like, you’re going to mess up your window config. I use Winner Mode to get back to stuff I’ve set up but it’s mind numbing and so I most often just use C-x 0, C-x 1, and C-x 2. C-x 3 is reserved for the rare occasions where I need to compare something side by side and it’s not an ediff situation.

Back when I was interested in this (2012), I tried to write code to force all activities to stay inside one window and failed. What I wanted was “what happens in a window, stays in a window” – and I guess I’d still be interested in working code. It’s just that I gave up on it.

Comments on 2020-08-26 Emacs without the bling

Hi, Alex, You can either prevent specific buffers from splitting the window with

(push (cons "\\*shell\\*" display-buffer--same-window-action) display-buffer-alist)
(push (cons "\\*scheme\\*" display-buffer--same-window-action) display-buffer-alist)
(push (cons "\\*Help\\*" display-buffer--same-window-action) display-buffer-alist)
(push (cons "\\*Buffer List\\*" display-buffer--same-window-action) display-buffer-alist)

That’s what I do. Those are the ones that pop up all the time and mess things up, and that I especially want and expect to just work like normal windows.

Or, instead of doing that, you can make the frame “unsplittable”, which, weird name for it, because you can still use C-x 3 and C-x 2 etc.

(add-to-list 'default-frame-alist '(unsplittable . t))

I don’t do that (I tried it but some things got weird) but I might if I was using a ton of weird new modes. But the take above, selecting a couple of favorite modes to just behave like normal windows and not pop up all the time, works fine.

The “unsplittable” doesn’t prevent you from doing C-x 2 and the like manually at all.

TL;DR display-buffer-alist is awesome and secondarily and kind of unrelated frames can be made unsplittable now.

Sandra 2020-08-29 21:01 UTC


Oh, that sounds very doable! Thanks!

– Alex Schroeder 2020-08-29 22:54 UTC


I should add ligatures and better emoji support one day. See Unicode, Ligatures and Color Emoji by Mickey Petersen.

– Alex Schroeder 2020-09-08 05:29 UTC

Add Comment

2020-08-14 Uses this

Somebody asked me for a “uses this” page… The short answer is: I use Emacs.

But here’s the long version. Because I’m vain. 😆

Portrait
Alex Schroeder

Who are you, and what do you do?

I’m a code monkey for a Swiss and German company. We do business software using Java and databases. It used to be mostly Oracle, these days it’s mostly PostgreSQL. This is still my first job. I’ve been doing it for more than twenty years. That is to say, the programming is boring, the tech isn’t exciting, and I’m old. But the part I love is switching projects, again and again. New team members, new project managers, new clients, new faces, new industries, I love that. I mean, it’s also a bit devoid of meaning, of course. In the grand scheme of things, who cares for car leasing, investment banking, furniture, call centers and credit cards? Nobody I love, that’s for sure.

And yet: I love to program. The world of programming is where I can make things. Like people tinkering with their cars, woodworking, knitting, sewing, playing music, baking, cooking, painting, I want to make things. Making things online comes easy to me and so I do it a lot. I only work a 60% job so that I have long weekends and long summer breaks, allowing me to follow my whim. One year it’s a local IRC server that acts as a gateway to Mastodon, the next year it’s a wiki using the Gemini protocol and markup as much as possible. I fall into projects in summer.

What hardware do you use?

I use a Purism Librem 13v2.

I have a bunch of external keyboards (Atreus, Keyboardio Model 01, Touchstream, Ergo Kinesis) but I don’t use them. I got used to laptop keyboards. And if my hands hurt, I know that I should just stop, not switch keyboards.

I also don’t use a mouse. I use the trackpad. When I’m drawing, I use an Apple Pencil and the iPad Pro. I rarely draw.

When I make music, I use various emulators on the iPad Pro, or the OP-1 or PO-33 K.O! by teenage engineering. I rarely make music.

For my podcasting I started recording voice memos with my phone; later I bought a second hand Snowball by Blue.

When I’m in the office, I use a regular Sennheiser Momentum for headphones. No wireless. No noise cancelling. I tried some noise cancelling headphones earlier and felt like it surpressed the background noise but not the voices and what I hate about the open plan office is the voices of my coworkers. A long time ago I had Shure in-ears. True plugs. Maybe I should get some in-ears again.

And what software?

The laptop runs PureOS, a Debian derivative. I picked a laptop that came with a Debian preinstalled. I hate installing software. I also dislike how out of date Debian can be, and I don’t like how they think the GNU manuals are not free, but overall, I still like package managers. Thank you so much!

In general, though, I’m not a operating system or distro hopping nerd. I used Slackware in the very old days and would not mind going back. I like to use Debian because I also use Debian on my server. My wife has an Apple laptop that I used for a long time, with Homebrew. Over the years I got angry about all the complications with iMovie, iTunes, iPhotos… it was difficult to get the stuff out again. The iTunes interface degraded over the years. Importing pictures into iPhotos led to crashes. It all started to feel like a thin veneer of sugar that was made to entrap me, and still didn’t deliver the stability I wanted. Instead I got mental models that didn’t fit the underlying models, if you know what I mean. The “events” and “playlists” cannot be found in the folders on disk, but the “rolls” are “importing events” and the “albums” are “folders” except when they’re “compilations”… Eventually I decided that I wanted to just use the filesystem again. Have files in folders. This I can understand. And on this level, Emacs can be used for practically everything.

Actual music playback is a command line tool like mpg321. When I look at PDFs, I use Evince because I find that Emacs’ document viewer mode is too slow. Or perhaps I just haven’t gotten used to it? Or is it the missing links? I don’t know. Maybe soon I’ll do without an external PDF viewer. 😁

When importing images from the iPhone, “Files” (is it still Nautilus? I have no idea) and whatever it invokes (gThumbs?) just work. It’s amazing that I don’t even know what this software is. Gnome something. It just works. This makes me happy.

When I’m organizing my images, I need a quick, keyboard driven user interface. Sadly, Emacs isn’t quick in this regard. I use Geeqie instead. The ability to use the ten digits for quick tagging is perfect. Go through the images and use 1 for album, 2 for delete, 3 for review, 4 for family, whatever, and then when you’re done, move the images around based on those temporary tags. ♥

When I’m editing my podcast, I use Audacity. I tried other programs, but most of the time their user interfaces are all tiny. I use a small laptop and I like big fonts and big icons. Audacity is the limit.

For graphics, I use Inkscape and Gimp (I hope to see Gimp replaced by Glimpse, soon!) – what a name. Yuck! It reminds me of that Quentin Tarantino movie and I hate Quentin Tarantino movies. On the iPad, the only app that I actually like using is Zen Brush 2. I somehow can’t get used to Procreate or Art Set or any of the other apps.

For making music, I use the iPad. The apps I like to use are PixiTracker (which is also available for other platforms), the iVCS3 emulator, the Model D emulator, the Animoog emulator, Synth One, and GarageBand (mostly for instruments like the Pipa, Erhu, Koto and Guzheng). I’d love to know more about music and must resist the temptation to buy more music making hardware without having taken full advantage of the things I already have. The temptations of capitalism…

The projects I work on in my spare time often use Perl 5. I sometimes try other languages: Python, Raku, Go, Scheme… but I always come back to Perl. Perhaps people just like to stick to their first language because that’s where their experience lies. You have made all the mistakes in the distant past and now everything comes naturally.

All the Perl projects I work on use the web as the universal user interface. I know, I know. I hate the web. It’s big and bloatet. And yet, the browser is the universal client. Huge, and bloated, and requiring a thousand engineers, I know. But none of the alternatives are great, either. I still haven’t written a GTK or Qt application, let alone something using X11, wxWidgets, or Tk. HTML and SVG it is, for me.

What would be your dream setup?

I have no idea. I want everything to just work, with no installation, and I love Emacs.

I’m fascinated by the Plan 9 concept of everything being a file, but at the same time, why can’t we have a system where everything is a file, and Emacs? Plan 9 has no Emacs. Emacs is like a universal Lisp machine: it provides a universal user interface to the underlying operating system and thus to the machine. It’s not perfect, yet. It often relies on tools that aren’t immediately available on Windows, for example – grep, find, sed – and you need external tools to play MP3 files and to edit their metadata.

Now that I use the Apple Pencil on the iPad Pro, I imagine how hard it is to draw on a traditional computer, even with a good tablet. And how would all of that work within Emacs? I would love to see all the Gimp stuff gobbled up by Emacs.

Comments on 2020-08-14 Uses this

I am really digging the love for EMACS that everyone is pouring out at the moment!! It’s probably because of its new release. I really enjoyed this gemini post 🙂 ~VIDAK

– elpherwVSLR9 2020-08-14 14:10 UTC


Haha, yeah! Emacs is great. I love it, too. And Elpher and Emacs together... my favourite way to comment on my wiki!

Karl Voit sent me a message on Mastodon about the naming and tagging he does using Geeqie with the addition of a small number of nifty scripts. An interesting workflow! And I totally agree with him: file names and folder structure is the kind of metadata that lasts a lifetime. Everything else is tricky.

– Alex

Add Comment

2020-08-14 How to comment using Elpher

If you visit this site using Elpher, you can leave a comment using Gemini. The comment can’t be too long. I think the total URL should be limited to about a thousand bytes, some of that is the URL without the query, and the query itself is going to be encoded… Who knows. Perhaps this server doesn’t actually check URL size? I have no idea and I have never tried. Ooops!

Here’s a video demonstrating it:

(Emacs using the Brutalist Dark theme…)

The video was recorded using Peek. It was edited and the audio was added using Pitivi. The audio was made on a tiny toy, the PO-35 speak. Basic recording was done using Audacity.

Comments on 2020-08-14 How to comment using Elpher

dogs are good

– elpherGiUS7i 2020-08-15 04:42 UTC


very cool, nice! great wiki 🙂

– elpherbqnGZw 2020-08-15 15:14 UTC


Hi from a patched Elpher! ~ michel

– 2020-08-15 23:24 UTC


Hah, I think most people don’t use the certificate’s Common Name to identify themselves but to identify the site they intend to use it for. Perhaps that’s some sort of usability issue: you want to create a new permanent certificate with your nickname as the Common Name, and save it using a filename identifying the site (or sites) you want to use it for. 😀

– Alex 2020-08-16 12:12 UTC


Nice. 🙂

– elpherzbK550 2020-08-16 12:30 UTC

Add Comment

2020-07-16 Emacs everything

These days I mostly use Emacs on my laptop. Sure, there’s all that stuff in the background. But in terms of applications I actually launch, I’d say I mostly use just Emacs.

I use Firefox for some websites, but I don’t actually do a lot of surfing. I spend a lot of time using Mastodon but with Bitlbee and the Mastodon plugin, I get the gist of things on IRC, and my IRC client is rcirc, in Emacs.

My Gemini client is Elpher, in Emacs. When I follow links in Elpher or IRC, they open in my default web browser, and my web browser is EWW, in Emacs.

(set browse-url-browser-function 'eww-browse-url)

Actually, there’s a little more customizing I do. First, I don’t need cookies:

(setq url-cookie-trusted-urls '()
      url-cookie-untrusted-urls '(".*"))

Cookies were invented for shopping carts and that’s where they should remain.

And I like to follow Gemini and Gopher links from my browser, so here’s how to handle them:

(advice-add 'eww-browse-url :around 'asc:eww-browse-url)

(defun asc:eww-browse-url (original url &optional new-window)
  "Handle gemini links."
  (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url)
	 (require 'elpher)
	 (elpher-go url))
	(t (funcall original url new-window))))

Did you know about Readability in EWW? Use R. 😀

I work a lot on the command line, but a lot of my work on the command line is actually just making directories, using git, and running tests, and all of that is better done in Emacs. Dired is my file manager, Magit is my git interface most of the time, Eshell is my shell.

I remember the days thirty years ago when I used Norton Commander on a 286. It was so much better than MS DOS 3.3 or whatever I used back then. But when I try to use Midnight Commander in a terminal, or Sunrise Commander in Emacs, soon enough I end up back in Dired.

I think there are some important things you need to do for Dired, though:

(eval-after-load "dired"
  '(require 'dired-x))

(setq dired-recursive-deletes 'always
      dired-recursive-copies 'always
      dired-deletion-confirmer 'y-or-n-p
      dired-clean-up-buffers-too nil
      delete-by-moving-to-trash t
      ;; trash-directory "~/.Trash/emacs"
      dired-dwim-target t
      dired-guess-shell-alist-user
      	  '(("\\.pdf\\'" "evince")
	    ("\\.jpg\\'" "feh"))
      dired-listing-switches "-alv")

Let’s go through them:

  • Some of the stuff I’m going to customise is actually part of the Dired extensions, so make sure those get loaded as well (but only when actually using Dired)
  • When deleting or copying directories, I always want to do this recursively.
  • When confirming things, I hate typing y e s and hitting the Return key. A simple y should be enough.
  • The buffer cleanup is another annoying question it likes to ask.
  • Very important: switching from rm to trash on the command line has been good for me a few times and so I was happy to see that Dired can also use the system trash.
  • Do-what-I-mean (DWIM) target means that whenever you have two dired buffers, the other buffer is suggested as a destination for commands that require one. Instant Norton Commander feelings: C-x 2 to split the window, change the directory in the current window, then copy or rename from one to the other.
  • When using ! on a file, Dired will suggest a command, but for JPG files the suggested command is xloadimage (where as for PNG files it is display), and for PDF files the suggested command is xpdf. I was interested in learning more about feh and my PDF reader is Evince, so that’s where these two settings come from.
  • The switches use -v in addition to the default switches, and that stands for natural numbers. Thus, foo-10 comes after foo-9, finally.

But there’s more:

(add-hook 'dired-mode-hook
	  (lambda ()
	    (local-set-key "E" 'emms-play-dired)
	    (local-set-key (kbd "C-c w") 'wdired-change-to-wdired-mode)))

Writable Dired (WDired) mode is cool because you can edit the buffer and rename a bunch of files all at the same time, using Emacs commands. In these situations using the rectangle commands come in super handy: C-x r k to kill a rectangle, and C-x r t to insert text on every line are my favourites.

EMMS is my music player, in Emacs. At home I don’t use it often, but at work I often need to listen to music. Fuck those open office plans. Project managers love it because they love to hear the buzz, get a feel for what the team is working on. For the team itself, however, it’s hell. We get to wear headphones almost the entire time because we can’t focus if we don’t. What a shitty way to program.

Back to EMMS... I usually use Dired to navigate to my music collection and then just hit E on a folder to play all of it. Perfect.

As loading EMMS can take a while because of the cache, I try to delay doing it. It’s only when nothing happens for a few seconds that I proceed. As you can see, my music player setup is super simple: I just use mpg321 or mpg123 or ogg123... As I said, it’s not fancy, can’t hit pause, don’t get lyrics, but it’s good enough for what I need: playing some music while I try to avoid the endless chatter of the people around me in the open plan office, GAAAAAAH!

(run-with-idle-timer
 10 nil
 (lambda ()
   (require 'emms-setup)
   (emms-standard)
   (if (executable-find "mpg321")
       (setq emms-player-list '(emms-player-mpg321))
     (define-emms-simple-player mpg123 '(file url)
       (emms-player-simple-regexp "mp3" "mp2")
       "mpg123")
     (setq emms-player-list '(emms-player-mpg123)))
   (when (executable-find "ogg123")
     (add-to-list 'emms-player-list 'emms-player-ogg123))))

Anyway, a small window into my Emacs life.

As you can see in the screenshot below, I use a big font, run Emacs maximised. I use them all maximised: Emacs, Tilix, Firefox, Evince... I don’t have time for tiling.

(cond ((find-font (font-spec :name "Iosevka"))
       ;; on windows, this defaults to a different font?
       (dolist (face '(default fixed-pitch))
	 (set-face-attribute
	  face nil
	  :family "Iosevka"
	  :height (if (eq (window-system) 'w32) 180 220))))
      ((find-font (font-spec :name "Noto Mono"))
       (set-face-attribute 'default nil :family "Noto Mono" :height 200)))

In the mode-line you can see my IRC setup. The theme I use is brutalist-dark. Thanks, @algernon.

I also deactivate the blinking cursor, the tool-bar, the menu-bar, and the scroll-bar...

;; deactivate some bling
(dolist (mode '(blink-cursor-mode
		tool-bar-mode
		menu-bar-mode
		scroll-bar-mode))
  (when (fboundp mode)
    (funcall mode -1)))

And some stuff I need:

Matching parenthesis are important for programming languages with lots of parenthesis, hehe.

Winner mode lets me go back to particular window configurations. Let’s say I have used a bunch of C-x 2 and C-x 3 and C-x + to get a few buffers to show in just the right way, and then a few uses of C-h i or C-h f or C-h v or M-x man to get help and it gets all messed up? Use C-c <left> to get back to that old layout.

Windmove allows me to use shift and the arrow keys to move from window to window Which is important if you have more than one in Emacs. If you have just two, C-x o is probably good enough.

Showing the column is sometimes important, I guess? Now I can’t remember when it ever was important. Something to be removed soon, I guess.

I also like my Emacs to not beep. I like completion to ignore case, and I don’t use double space to end sentences. When this is really important I use non-breaking spaces after abbreviations. I’ve changed my Caps Lock key to be the Compose Key. Very useful!

;; active some other bling
(show-paren-mode 1)
(winner-mode 1)
(windmove-default-keybindings)
(column-number-mode 1)

(setq visible-bell t
      completion-ignore-case t
      read-buffer-completion-ignore-case t)
(setq sentence-end-double-space nil)

And here’s the screenshot...

Screenshot

Tags:

Comments on 2020-07-16 Emacs everything

My config files are online... see my Emacs setup.

– Alex Schroeder 2020-08-14 10:07 UTC

Add Comment

2020-07-02 An overview over my Gemini projects

A while ago I started writing lots of stuff for Gemini. Time for an overview, both for myself and for you, the hypothetical reader. 😀

I’m not going to link to the various blog posts where I’ve talked about the various projects before. If you want to find them, take a look at the Gemini tag.

Gemini Server is a server that serves an existing Oddmuse wiki via Gemini protocol. It also tries translate the wiki text from a typical Markdown + Wiki mess like the one I’m using on this wiki here into Gemini format. I think it works and you can look at it using your favourite Gemini Client. It’s at alexschroeder.ch:1965.

Gemini & Titan for Bash are two functions for bash. I use them all the time to debug stuff. The gemini function uses the Gemini protocol to fetch stuff from the Internet and dumps it. No formatting, header and all. The titan function uses the Titan protocol to write text and files to a Titan-enabled Gemini server, such as the ones I run.

Titan is where I’ve written down a few words on the protocol I use to upload files to my wiki. There hasn’t been much talk about the Titan protocol, partly because I felt pretty much alone in my interest for wikis. On the Gemini mailing list, people were talking about using SFTP or mail to upload or comment, or about how they disliked commenting, and so on. I figured I’ll just have to implement some stuff and then maybe other people might get interested, once it’s shown its utility, even if we then change small aspects of the protocol. If you want to talk about Titan, feel free to contact me, or comment or edit that Titan page. It’s also hosted on a wiki!

Community Wiki, where the Titan page is being hosted, is also reachable via Gemini and editable via Titan. The quality of the translation from wiki text to Gemini format isn’t all that great because it never switched to Markdown. It’s mostly Wiki Creole and a bunch of specific extensions. It’s available at communitywiki.org:1966.

Next, I wanted to see how to translate a dense hypertext like Wikipedia to the Gemini format and I wrote Gemini Wikipedia, a Wikipedia proxy strips most of the links in order to provide you with a nice reading experience; it also tries its best to translate tables to text (probably not a good way to read those tables if you’re blind, sadly). If you really want to, you can always get the HTML including all the links, and depending on your browser, it might work.

I later rewrote that code and now it’s part of the Gemini Wiki config file I’m using at The Transjovian Council. It’s available at The Vault. I recommend starting with the Project Gemini page. It’s the page I used to check my code as I was developing it. 😀

Gemini Wiki, finally, is my wiki for everybody. It builds on the Gemini Server I used for this site. It uses a Gemini format internally. It allows you to add pages and files to the wiki directly. It even has a very simple, read-only web interface! It has “spaces” so you can host multiple wikis for different people. I’ve been using my installation to write about it. It’s at The Transjovian Council, and as I said, you can also access it via a web browser on the same port.

Oh, and if you’re an Emacs person, there’s more...

Gemini Write is an extension to Elpher, the Emacs Gopher and Gemini client, which allows you to edit pages right there, in Emacs. I also started working on a “multiple buffers” branch for Elpher. You can find it in The Lambda Lab’s git repository, via Gopher!

Ah, and before I forget: here’s a video of me editing Gemini Wiki, from Emacs! You might have to right-click the preview image and choose “Play” from the context menu. It depends on your browser and your settings, I guess.

So happy. 😀

Tags:

Comments on 2020-07-02 An overview over my Gemini projects

Hello, I notice I can’t play the video as my browser (Chrome) doesn’t show the video controls by default. After inspecting the source code, I think you mistyped the HTML attribute “controls”, you wrote “control”, that is, a “s” was missed.

Xu Chunyang(徐春阳) 2020-07-11 13:57 UTC


Thank you so much! That was indeed the problem. And now it works for Firefox as well.

– Alex Schroeder 2020-07-11 14:36 UTC

Add Comment

2020-06-11 Demonstrating Gemini Wiki

This wiki is also served via the Gemini protocol (something between Gopher and the Web as we know it). I’ve written an extension that allows me to write back to the wiki (and not just leave a single line of comments).

In case you’re curious, today I made a short 50s video!

Made using Emacs, Elpher, Gemini, Oddmuse, Peek, and Garage Band. 😀

If you’re interested in how this works, I think the two two bash functions I wrote make two good examples: gemini allows you to read and titan allows you to write.

Tags:

Comments on 2020-06-11 Demonstrating Gemini Wiki

Let’s see how this works with a gemini client.

– Anonymous 2020-06-11 22:52 UTC


If you want to be non-anonymous, I guess you need Gemini Write support. If you have it, just edit the page and there you go.

Or I could add another back and forth to ask your name every time you comment. Do you think that would be worth it?

– Alex Schroeder 2020-06-12 18:05 UTC


Starting a series of wiki pages on how to set up your own Gemini Wiki using Oddmuse.

– Alex Schroeder 2020-06-13 20:25 UTC

Add Comment

2020-06-05 Gemini Write

My new package gemini-write can be used to edit this site via my Gemini Write proposal.

In order to browse Gemini sites, I use Elpher.

In order to get Gemini highlighting, I use Gemini Mode.

Once you have all three packages installed, visit this site, find a page you want to edit, follow the link to the “Raw text” at the bottom and then use e to edit it. The raw pages are the only pages that can be edited. Use C-c C-c to save, use C-c C-k to cancel. Customize elpher-gemini-tokens to set passwords, tokens, or whatever you need in order to edit sites.

Currently this only works on this site, I guess.

And I currently don’t have a markup rule to render Gemini links, but I’ll add that as soon as somebody posts one. 😀

Test it here: Gemini Test.

Tags:

Comments on 2020-06-05 Gemini Write

I wonder if you also plan to support search functionality at some point?

deshipu 2020-06-05 13:57 UTC


Yes. I did that just now.

– Alex Schroeder 2020-06-05 21:21 UTC


There is still some sort of bug where saving doesn’t always work and if it does not, then whatever you wrote is lost. That is definitely disappointing. I’m suspecting that it depends on the page name.

– Alex Schroeder 2020-06-07 09:32 UTC


I’m starting to see the difficulties of rendering the raw wiki text to Gemini using regular expressions. That part is definitely trickier than I thought.

– Alex 2020-06-08 15:54 UTC


Video! 😀

– Alex Schroeder 2020-06-11 18:12 UTC

Add Comment

More...

Comments


Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. Note: in order to facilitate peer review and fight vandalism, we will store your IP number for a number of days. See Privacy Policy for more information. See Info for text formatting rules. You can edit the comment page if you need to fix typos. You can subscribe to new comments by email without leaving a comment.

To save this page you must answer this question:

Just say HELLO