2025-01-06 Emacs news

| emacs, emacs-news

[2025-01-06 Mon]: Fix typo in exitter's name

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, communick.news, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post

Yay Emacs 8: which-key-replacement-alist

| yay-emacs, emacs

I wish I could memorize all these keyboard shortcuts in Emacs, but I just don't use some commands often enough to build the muscle memory for them, especially since I have so many context-sensitive shortcuts thanks to Embark. That's why which-key is great. It used to be a separate package, but it's now part of Emacs 30. You just have to turn on which-key mode, and then, if you hesitate in the middle of a keyboard shortcut, Emacs will show you what you can do. It turns out that you can customize this menu,so here are some tweaks I'm trying. First, I want to change which-key-sort-order to the one that sorts by description. This groups similar functions together. Then I want to change the labels using which-key-replacement-alist. Let's try it without the dashes between words. Now let's turn on multiple replacements and make things even simpler. I can even use Unicode to make it easier to spot certain commands. And of course there's an Elisp way to customize all of this. I want to see if these little tweaks can help me use Emacs better. If you use which-key, maybe you'll also want to customize your menu. Let me know what you figure out!

You can watch this on YouTube, download the video, or download the audio.

Things I'm trying:

(with-eval-after-load 'which-key
  (setopt which-key-allow-multiple-replacements t
        which-key-sort-order 'which-key-description-order
        which-key-replacement-alist
        (seq-map
         (lambda (rep)
           `((nil . ,(elt rep 0))
             . (nil . ,(elt rep 1))))
         '(("my-subed-set-timestamp-to-mpv-position" "set to MPV")
           ("my-embark-org-copy-exported-url" "⭐🗐🔗 copy exported URL")
           ("my-subed-copy-timestamp-dwim" "copy")
           ("my-sketch-insert-file-as-link" "insert")
           ("my-geeqie-view" "geeqie")
           ("my-journal-edit" "edit")
           ("my-org-link-qr" "qr")
           ("my-image-open-in-" "")
           ("org-babel-" "ob-")
           ("next" "🠆")
           ("previous" "🠄")
           ("my-image-" "")
           ("my-embark-org-blog-" "")
           ("embark-collect" "⇶ collect")
           ("my-embark-org-" "")
           ("my-" "")
           ("embark-" "")
           ("embark-act-all" "all")
           ("embark-become" "become")
           ("embark-collect" "collect")
           ("-" " ")))))

To use which-key as part of Embark, see the Embark wiki's suggested configuration.

View org source for this post

A brief foray into Underdog, a realistic Minecraft modpack; returning to Total Animation

| minecraft

A+ often enjoys watching Minecraft videos on Youtube where streamers take on challenges like surviving harder, more realistic worlds. We briefly gave RL Craft a spin the other day, but I died to a dragon and that wasn't realistic enough for A+, so we checked out Underdog today.

We couldn't get Underdog to work under GDLauncher on her computer even when I changed the Java interpreter and memory settings as suggested in the Underdog installation instructions. I installed PrismLauncher on her computer and that worked fine.

As usual, when we started the world, we set it to peaceful and turned the day/night cycle off. The early progression quests went all right, except for the one about obtaining 32 balls of clay. We found a few, but I'm not sure if there were enough clay blocks near our spawn or maybe they were just hard to see under the water. I liked how the process of making charcoal involved making a pit and burning the stacked firewood blocks under a nonflammable material (I used dirt).

2025-01-02_12.27.05.png
Figure 1: Our little crafting area in Underdog.
2025-01-02_12.27.10.png
Figure 2: Making some charcoal by burying burning wood under dirt

A+ wasn't a fan of how much work was involved in everything, though, so I'm not sure we'll return to this world. I think when she says "realistic", she's looking for something more like Total Animation than TerraFirmaCraft. Here's what Total Animation looks like:

2025-01-02_14.17.33.png
Figure 3: Screenshot of Total Animation

(You can tell I built the house because it's a boring box-like thing made with whatever wood was handy.)

We last checked out Total Animation in October. It's a little too laggy on my Lenovo P52 laptop, so I usually play without the shaders and visual effects that make it special. A+ has more patience for that, and since she plays in Windows, her P52's (small) Nvidia GPU can accelerate it enough to be tolerable.

There are a ton of modpacks that focus on more realistic textures/shaders/etc., so she'll probably flip through a few of them. I might as well practise my journaling along the way.

View org source for this post

Using image-dired to browse the latest screenshots from multiple directories

Posted: - Modified: | emacs, image, org, link

[2025-01-06 Mon]: Patch in progress, Stefan Kangas is looking into it.

Since A+ and I play lots of Minecraft together, I figured it's a good opportunity to slowly get her into the idea of documenting learning. Besides, I can always practise it myself. Screenshots are handy for that. In Minecraft Java, F1 hides the usual heads-up display, and F2 takes the screenshot. Usually, when I start taking screenshots. A+ starts taking screenshots too. I want to build on her enthusiasm by including her screenshots in notes. To make it easy to incorporate her pictures into our notes, I've shared her GDLauncher folder and her Videos folder with my computer using Syncthing so that I can grab any screenshots or videos that she's taken.

In Emacs, image-dired makes it easy to see thumbnails. The neat thing is that it doesn't just work with a single directory. Just like Dired, you can give it a cons cell with a directory in the first part and a list of files in the second part as the first argument to the function, and it will display those files. This means I can use directory-files-recursively to make a list of files, sort it to show most recent screenshots first, limit it to the most recent items, and then display a buffer with thumbnails. image-dired-show-all-from-dir reports a small error when you do this (I need to send a patch upstream), so we hush it with condition-case in my-show-combined-screenshots.

(defvar my-screenshot-dirs
  '("~/recordings"
    "~/.var/app/org.prismlauncher.PrismLauncher/data/PrismLauncher/instances/"
    "~/sync/gdlauncher-instances/"))
(defvar my-recent-screenshot-limit 50)

(defun my-combined-screenshots (&optional limit)
  (seq-take
   (sort
    (seq-mapcat (lambda (dir)
                  (directory-files-recursively dir "^[0-9][0-9][0-9][0-9]-.*\\.\\(png\\|webm\\)"))
                my-screenshot-dirs)
    :key #'file-name-base
    :lessp #'string<
    :reverse t)
   (or limit my-recent-screenshot-limit)))

(defun my-latest-screenshot ()
  (car (my-combined-screenshots)))

(defun my-show-combined-screenshots (&optional limit)
  "Show thumbnails for combined screenshots."
  (interactive (list (when current-prefix-arg (read-number "Limit: "))))
  (condition-case nil
      ;; ignore errors from image-dired trying to set default-directory
      (image-dired-show-all-from-dir
       (cons (car my-screenshot-dirs) (my-combined-screenshots limit)))
    (error nil)))
2025-01-02_08-19-32.png
Figure 1: The result of my-show-combined-screenshots

In the *image-dired* buffer created by my-show-combined-screenshots, I can use m (image-dired-mark-thumb-original-file) to mark images and C-u w (image-dired-copy-filename-as-kill) to copy their absolute paths.

To make it easier to create links to a file by using org-store-link (which I've bound to C-c l) and org-insert-link (C-c C-l in an Org buffer), I can define a link-storing function that takes the original filename:

(defun my-org-image-dired-store-link ()
  (when (and (derived-mode-p 'image-dired-thumbnail-mode)
             (get-text-property (point) 'original-file-name))
    (org-link-store-props
     :link (concat "file:" (get-text-property (point) 'original-file-name)))))

(with-eval-after-load 'org
  (org-link-set-parameters
   "image-dired"
   :store #'my-org-image-dired-store-link))

To make it easier to insert the marked links that have been copied as absolute paths:

(defun my-org-yank-file-links-from-kill-ring ()
  (interactive)
  (dolist (file (read (concat "(" (current-kill 0) ")")))
      (insert (org-link-make-string (concat "file:" file)) "\n")))

I usually want to copy those files to another directory anyway. I have a my-org-copy-linked-files function in Copy linked file and change link that copies the files and rewrites the Org links. This means that I can copy my notes to an index.org in a directory I share with A+, save the images to an images subdirectory, and export the index.html so that she can read the notes any time she likes.

This is part of my Emacs configuration.
View org source for this post

Cuberventures: Early game Create Mod

| minecraft

A+ likes exploring different Minecraft Java modpacks in creative mode. We're currently playing FXNT Create 2. I like challenging myself to figure things out in survival mode, so I'm getting a lot of practice in building early-game survival farms with Create. My setup has changed a little bit over the last few modpacks/worlds. I usually start by mining enough iron and zinc to make a mechanical press so that I can make the iron sheets used in other machines. Then I make a mechanical mixer so that I can make andesite nuggets more efficiently. Then I make a millstone and an encased fan so that I can process cobblestone and wash the resulting gravel manually.

Once that's in place, I can start making more elaborate things.

2025-01-01_16.47.59.png
Figure 1: A simple radial tree farm uses a mechanical saw.
2025-01-01_16.47.03.png
Figure 2: This time, I experimented with putting my crop farm under the tree farm.

I used to have the encased fans just blowing horizontally. After I learned that I can use encased fans to blow upwards through a depot, I switched to setting up my blasting/smoking/washing stations vertically so that I didn't burn myself as often.

2025-01-01_16.36.12.png
Figure 3: My blasting/smoking/washing stations

The most recent thing I added to this world is this cobblestone-gravel-iron nugget machine.

2025-01-01_13.27.19.png
Figure 4: The cobblestone generator…
2025-01-01_13.28.06.png
Figure 5: … feeds into a millstone/washer
2025-01-01_13.29.02.png
Figure 6: All together now
2025-01-01_16.07.40.png
Figure 7: I changed the cobblestone output to feed into two millstones, dropping the results with chutes

I needed to upgrade to a large waterwheel to drive the two millstones along with the fans.

Next things I'll probably try:

  • The lava farm is filling up nicely, so I can put some pipes underneath it and have a pump move lava into a basin for making andesite. That'll give me something to do with the flint from the iron nugget farm. I'll need to mine some copper first, though.
  • I can start mining for diamonds so that I can get obsidian and go to the Nether. I made a rope pulley + drills mining contraption, but (a) I think it got stuck after going past some lava and water, and (b) the shaft it made uncovered a deep dark biome, so… that's a little scary. Maybe I'll do some branch mining, or cave mining when the world is set to peaceful.
View org source for this post

Editing videos with Emacs and subed-record.el

| emacs, subed, video

I want to document more of my Minecraft adventures with A+. Video is a natural way to do this. It builds on her familiarity with the tutorials and streams she enjoys watching. I set up OBS on her laptop and plugged in my Blue Yeti microphone. We did our first interview yesterday. I edited and subtitled it (because why not!), uploaded it as an unlisted YouTube video, and shared it with her dad, sister, and cousins.

I did the video editing in Emacs with subed-record. First, I used WhisperX to transcribe the video, and I used subed-align to fix the timestamps with aeneas. I normalized the audio with Audacity and I exported the .opus file for use in subed-record.el. Then I added NOTE #+SKIP before times I wanted to remove, like when she asked for a retake. Here's what that subtitle markup looks like:

WEBVTT

NOTE #+SKIP

00:00:00.000 --> 00:00:16.679
And then I'll record in my side also
and we'll just put it in somehow.
Somehow. Okay. We can edit that, right?
Yeah, we'll learn how to edit things.
It'll be great.

NOTE
Introduction
#+AUDIO: cuberventures-001.opus
[[file:intro.webm]]
#+OUTPUT: cuberventures-001-fxnt-create-2-windmill-home-cafe-trains-hotel-half-underwater.webm

00:00:16.680 --> 00:00:19.399
Okay, so now we're here with <username>.

00:00:19.400 --> 00:00:23.039
I want to find out what you like about Minecraft and

00:00:23.040 --> 00:00:26.079
all the cool things that you have been building lately.

This was a little different from my usual video creation workflow, where I record the audio and the video separately. When I wrote subed-record.el, I assumed I'd edit the audio first, choose images/GIFs/videos that were already ready to go, and then combine those visuals with sections of audio, speeding things up or slowing things down as needed. Now I wanted to apply the same edits to the video as I did to the audio. A+ did a great job of looking at stuff in Minecraft while talking about them, so I wanted to keep her narration in sync. I added some code to allow me to specify a same-edits keyword for the visuals. That meant that I would use the same selection list that I used for cutting the audio. Here's what that subtitle markup looks like:

NOTE
[[file:2024-12-31 10-35-14.mkv]]
#+OPTIONS: same-edits

00:00:43.860 --> 00:00:45.941
Shall we take a tour of my world?

00:00:45.942 --> 00:00:50.079
Sure, let's tell people which mod pack this is.

00:00:50.080 --> 00:00:55.639
This is FXNT Create 2, also known as FoxyNoTail Create 2.

NOTE Windmill

00:00:55.640 --> 00:00:58.239
I've got this little bit of path leading to the interview

00:00:58.240 --> 00:01:01.839
room. This is my unfinished windmill. I've been meaning to

This workflow lets me cut out segments in the middle of the video, like this:

00:17:30.200 --> 00:17:33.119
great start for a tour. I'm looking forward to seeing what

00:17:33.120 --> 00:17:34.112
you will build next.

NOTE #+SKIP

00:17:34.113 --> 00:18:02.379
Do you have any last words before
we try to figure out this video editing thing?
Yeah. We'll cut that last part out.
Let's just do a retake on that last part.
Someday. Out here. Okay. There you go.
This is a beautiful view.

00:18:02.380 --> 00:18:08.119
The last things I want to say about this world is there'll be

I also wanted to start the video with a segment from my recording, so we could see her avatar on screen during the introduction. She kept her computer on first-person POV instead of changing the camera. I used mpv to figure out the timestamps for the start and end of the part that I wanted to use, then I used ffmpeg to cut that clip. I added a comment with a link to that video in order to use it before the main video. That's the [[file:intro.webm]] in the first section's comments.

After testing a small section of the transcript by selecting a region and using subed-record-compile-video, I deselected the region and used subed-record-compile-video to produce the whole video.

I also modified subed-record-compile-subtitles to include the other non-directive comments, so I can include the section headings in the raw VTT file and have them turn up in the exported version. Then I can use the new subed-section-comments-as-chapters command to copy those as chapters for the YouTube description.

We're not going to share that particular video yet, but I'm looking forward to trying that technique with videos about stuff I'm figuring out in Minecraft or Emacs. It's also tempting me to think about ways to specify transitions like crossfades and other fancy effects like overlays.

I like using the transcript as the starting point for video editing. It just makes sense to me to work with it as text. I also like this experiment with documenting more of our Minecraft experimentation. It seems to get her talking and encourages her to build more. I'm looking forward to learning more about Minecraft and making videos too.

We did another video today using the new shortcuts I've just set up for toggling OBS recording. This time we didn't even need to do any editing. I used Org Export to make her a little HTML file that had the two videos on it, so she can review it any time. Onward!

View org source for this post

2024-12-30 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Hacker News, lobste.rs, kbin, programming.dev, lemmy.world, lemmy.ml, communick.news, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post