Sacha Chua: 2021-01-18 Emacs news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

-1:-- 2021-01-18 Emacs news (Post Sacha Chua)--L0--C0--January 18, 2021 06:29 AM

Amit Patel: Building Emacs 27 on Apple ARM M1

On Mac, I sometimes run a prebuilt binary and sometimes compile my own. For Apple M1 (ARM) I am using the x86 binaries from emacsformacosx.com but I wanted to try compiling a native ARM version too. I saw that the work branch of Mitsuharu Yamamoto's Mac port already has patches applied, so I decided to try it.

Screenshot of Emacs 27 compiled on Apple ARM M1

Make sure /opt/homebrew/bin (ARM homebrew) is earlier in your path than /usr/local/bin (Intel homebrew).

EMACSAPP=/tmp/Applications
brew install coreutils pkg-config libxml2 jansson gnutls autoconf gnu-sed
git clone --depth 1 --single-branch --branch work \
    https://bitbucket.org/mituharu/emacs-mac.git
cd emacs-mac
./autogen.sh

and then build:

make clean
find . -name \*.elc -exec rm '{}' ';'

./configure \
     --with-mac-metal --with-xml2 --without-imagemagick --with-json \
     --with-modules --without-makeinfo \
     --prefix=$EMACSAPP/Emacs.app/Contents/MacOS \
     --enable-mac-app=$EMACSAPP --enable-mac-self-contained
make -j3
mac/Emacs.app/Contents/MacOS/Emacs -q # test it
make install

You should see it bring up a window with:

This is GNU Emacs 27.1 (build 1, aarch64-apple-darwin20.1.0, Carbon Version 164 AppKit 2022.1)
 of 2020-11-30
Copyright (C) 2020 Free Software Foundation, Inc.

Updates

  • [2020-11-30] I've gone back to the emacsformacosx.com version for now because I've run into various issues, including modules (like vterm) not working.
  • [2020-12-01] The emacsformacosx.com version flickrs a lot when using Rust + LSP + posframe, due to this issue, so I'm now using the Mitsuharu version compiled for x86.
  • [2020-12-03] I had some issues with *.elc files from previous compiles not being recompiled so I ended up deleting all the *.elc files in the emacs build folder, and that resolved the problem.
  • [2020-12-05] Even though I removed the *.elc files from built-in modules, I had weird issues with the elpa modules, so I forced recompilation of everything with (byte-recompile-directory "~/.emacs.d/elpa" 0 t).
  • [2020-12-07] I was able to switch back to the ARM version. Recompiling elc resolved the issues I had previously, except I still am not using modules. The ARM version seems faster but I don't know a good way to measure.
  • [2020-12-13] When compiling the vterm module, Emacs crashed in dlopen, but it seemed to work when I started Emacs again. So modules … seem to work?
  • [2021-01-07] I learned that Homebrew emacs works on arm, and Homebrew emacs-plus also works on arm. I haven't tried either because I'm happy with the version I compiled. But I think these would be the first things to try if you don't want to compile your own.
-1:-- Building Emacs 27 on Apple ARM M1 (Post Amit (noreply@blogger.com))--L0--C0--January 18, 2021 06:10 AM

Irreal: Yesterday’s Date

One of my daily tasks involves making a log entry in which I have to use yesterday’s date. That’s pretty easy with Org dates but the dates in the log don’t have the usual Org markup of square or angle brackets. They’re just plain dates like this: 2021-01-16. I have a function to enter dates like these bound to Ctrl+c d. For a long time, I just used this shortcut to enter today’s date and fixed it manually. That was easy enough except at a month change but was still pretty silly.

A couple of years ago, I got fed up and decided to write a function that would directly enter yesterday’s date. Getting yesterday’s date is way harder than it should be but after a bit of research, I found the secret spell and wrote the function. Recently, I’ve had a need to enter the date from two days ago. The first couple of times I just entered yesterday’s date with my function and fixed it manually but rather than go through another long period of making manual adjustments, I thought I’d just fix my function to take a numerical argument so that it could enter a day from \(n\) days ago.

Unlike the original function, the change was trivial. If you have a similar need, here’s the function:

1: (defun jcs-yesterday (days)
2:   "Insert yesterday's date."
3:   (interactive "p")
4:   (let ((ts (decode-time)))
5:     (setf (nth 3 ts) (- (nth 3 ts) (if days days 1)))
6:     (insert (format-time-string "%Y-%m-%d" (apply #'encode-time ts)))))

As an (unintended) side effect, I can even enter a negative number and get a date \(n\) days in the future. If your use case involves entering dates in the future, you can change the meaning of \(n\) so that positive arguments move forward by changing the \(-\) sign in line 5 to \(+\).

-1:-- Yesterday’s Date (Post jcs)--L0--C0--January 16, 2021 05:46 PM

Irreal: Knuth’s Literate Programming Paper

Literate Programming. Back in 1984 when Knuth published his paper proposing Literate Programming, he believed that the concept would take over the programming world. I remember him saying that companies that failed to adopt Literate Programming would soon fall behind those that do. It hasn’t worked out that way.

Literate Programming failed to gain traction until recently. Now a sort of watered down version can be found in the various programming language notebooks. Org-mode Babel can—but doesn’t have to—support Knuth’s model so after almost 4 decades one could say that Literate Programming is finally seeing its day in the sun.

Although I love the idea, I’ve never been able to embrace the Knuth model. I want—need—to see the whole program all at once, which isn’t practical with the Knuth model. Even with Babel, I don’t use the full Literate Programming capabilities. I prefer the Literate Devops model used by Howard Abrams, a weaker model similar to that provided by the programming language notebooks.

Given the resurgence of interest in Literate Programming, it seems appropriate to revisit Knuth’s original paper. Vivek Haldar has added it to his Read A Paper series and gives a nice exposition of the paper. The video is just over 9 minutes so you can watch it on a coffee break. If you have an interest in Literate Programming in any of its incarnations, it’s worth taking a look at where it all started.

-1:-- Knuth’s Literate Programming Paper (Post jcs)--L0--C0--January 14, 2021 11:07 PM

Irreal: Setting Up Mu4e

Yesterday’s post discussed David Wilson’s video on setting up and using authinfo. In that video, Wilson mentioned his videos on setting up mu4e and how authinfo fit into configuring mu4e and mbsync.

Those videos are also worth watching. The first talks about setting up mu4e and mbsync for a Gmail account. The second—more interesting—video explains how to use mu4e on multiple accounts. Together, the videos cover two of the problems that I read about the most:

  • How to set up mbsync up for Gmail.
  • How to set up multiple accounts with mu4e.

If you’d like to move your email to Emacs, I can unreservedly recommend mu4e although there are other possibilities. Wilson’s two videos will help you get things running.

The first video is a couple minutes over an hour and the second is 31 minutes so you’ll definitely need to schedule some time but if you’re stuck getting mu4e configured, they could be just what you need to get unstuck.

-1:-- Setting Up Mu4e (Post jcs)--L0--C0--January 13, 2021 05:54 PM

Irreal: Setting Up and Using Authinfo With Emacs

Once you start moving more and more of your computing tasks into Emacs, you’re going to need a way of handling passwords. Mail is the canonical example but there are also things like blogging sites, ftp servers and other functions that you want to access from Emacs but that require a password.

With mail, for example, you need a login and password to retrieve your mail from, say, your mail provider’s IMAP server and you may need another set for their SMTP server so you can send mail. One solution is to simply add these to your configuration files but that’s horribly insecure. Of course, as usual, Emacs has us covered. The proper way of doing this is to put all the login/password information into an authinfo file and encrypt it. Emacs will read, decrypt, and parse this file to get the required login/password, requesting the key to decrypt the file if necessary.

Setting this up can be a bit tricky but David Wilson has a nice video that explains how to set up and use the authinfo system. He takes you step-by-step through the process but be sure to read Chris Wellon’s (skeeto) comment on how and why to use an elliptic curve instead of the RSA-based key that Wilson uses.

The video is 38 minutes, 13 seconds so plan accordingly.

-1:-- Setting Up and Using Authinfo With Emacs (Post jcs)--L0--C0--January 12, 2021 08:19 PM

Timo Geusch: Moving this blog to a static site – this time I’m serious (because org-mode)

I have been toying with the idea of migrating this blog to a static site to simplify its maintenance for some time. While WordPress is a great tool, this blog is a side project and any time I have to Read More

The post Moving this blog to a static site – this time I’m serious (because org-mode) appeared first on The Lone C++ Coder's Blog.

-1:-- Moving this blog to a static site – this time I’m serious (because org-mode) (Post Timo Geusch)--L0--C0--January 12, 2021 03:00 AM

Andrea: Emacs as your code-compass: let history show you which files to edit next

See which files need changes after you edit the current one
-1:-- Emacs as your code-compass: let history show you which files to edit next (Post)--L0--C0--January 12, 2021 12:00 AM

Sanel Zukan: Edit files in (remote) Docker containers

I always had problems remembering Docker commands: to run a shell in a container, should I use docker run or docker exec? Wait, I probably need to "attach" the terminal to the running container. No problem, let's try docker attach. Ooops...

These commands initially made no much sense to me - run and exec sounds like an alias to me and attach; well, Docker authors clearly had the idea that attaching to container and attaching shell input (typing commands inside container shell) are entirely unrelated things.

Because of this, I kept personal docker.org file with all the notes how I'm going to start a container, run something in it, and so on.

Here is another problem. Most containers are built to be minimal, providing only necessary stuff for containerized application. So, I'd frequently find things like a complete JDK stack, tons of python libraries, or many nodejs packages.

But not a single editor. No vim, emacs, nano... not even "the standard editor" ed ;) You'll get cat, sometimes less, but try to modify something with those.

I'm aware that container purists will scream at me that I should not edit anything inside containers, but let say that theory and edge cases from real life are on the complete opposite side. Not once I had to hack things around, inside a container, without shutting it down the application.

So, Emacs to the rescue, as usual. Thanks to awesome docker-tramp mode, Emacs can access to Docker containers trough TRAMP and bring all the goodies that comes with it: dired, eshell, shell, file syntax highlighting and, yes, editing.

Download it, load it, and let see what it can do.

For example, to access a locally running container, with CONTAINER_ID id:

C-x C-f /docker:CONTAINER_ID:/

evil-mode users will use:

:e /docker:CONTAINER_ID:/

And dired will be running inside container. eshell and shell will work as well.

There is more. You can access to remote container via multiple hops with the following:

C-x C-f /ssh:remote-server-ip|docker:CONTAINER_ID:/ 

Image will help:

docker-multiple-hops1.png

You can also have a more complicated setup, like jumping through bastion host(s):

C-x C-f /ssh:remote-server-ip1|ssh:remote-server-ip2|docker:CONTAINER_ID:/ 

docker-multiple-hops2.png

There is even more!

Let say you want to evaluate (or run) python code inside that remote Docker container, assuming the container has installed python? No problem at all. Do this, as explained here:

C-x C-f /ssh:remote-server-ip|docker:CONTAINER_ID:/ 
M-x run-python

And you'll get a python shell inside your Emacs. Open some local python file and start evaluating python expressions - they will be executed in a remote container.

Notice that docker-tramp has a couple of caveats:

  1. It expects the container to be up and running and will not start it.
  2. It doesn't have auto-completion of container ids unless you apply this patch.

However, for me, it is good enough :)

-1:-- Edit files in (remote) Docker containers (Post)--L0--C0--January 11, 2021 11:00 PM

Irreal: Adding a Third Monitor to EXWM

Twelve or thirteen years ago, I got my first Mac. Fast forward to today and you’ll find that the Irreal bunker is firmly in the Apple ecosystem. One of the things I don’t miss—at all—is struggling with getting X configured. I’m told by reliable sources that things are much easier now but the horror of X configuration was brought back to me by Tory Anderson’s post on how he added a third monitor to his EXWM configuration.

I love the idea of EXWM and wish it were available for the Mac but for now, I’ll have to look on enviously. Anderson runs EXWM and had it set up for his main monitor and his laptop screen. Then he got another monitor and wanted to add it to his EXWM system. His post is a detailed step-by-step tutorial on how to do that.

If you read his post, you’ll see what I mean about X configuration. He had to do some fiddling with his X configuration to get things running. No doubt I’m just being a sissy and making things seem harder than they are but I’ve grown soft living in the Apple walled garden where none of this is necessary. If you’re looking to add another monitor to your setup, you should take a look at Anderson’s post.

-1:-- Adding a Third Monitor to EXWM (Post jcs)--L0--C0--January 11, 2021 10:08 PM

Marcin Borkowski: Deleting last entry from the kill ring

The Emacs’ kill ring is a brilliant and extremely useful concept. It has some drawbacks, too, though. Probably the biggest one is that the entries there persist for quite some time. This is, after all, what it’s for – but sometimes you explicitly want some entry to disappear. This is of course the case when you have some password or a similar thing you copy to e.g. config files.
-1:-- Deleting last entry from the kill ring (Post)--L0--C0--January 11, 2021 03:09 PM

Sacha Chua: 2021-01-11 Emacs news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

-1:-- 2021-01-11 Emacs news (Post Sacha Chua)--L0--C0--January 11, 2021 06:20 AM

Tory Anderson: Applying a replacement map to characters in emacs

The Problem I have text in Cyrillic and need to replace individual characters with their transliteration. I have a tiny json of the mappings: {"в": "v","а": "a","ф": "f","ё": "yo","д": "d","ж": "zh","ы": "y","э": "e","л": "l","щ": "shch","я": "ya","й": "j","у": "u","н": "n","г": "g","с": "s","п": "p","ч": "ch","б": "b","х": "kh","е": "ye","ъ": "\"","з": "z","ю": "yu","ь": "'","ш": "sh","о": "o","к": "k","и": "i","ц": "ts","м": "m","т": "t","р": "r"} And I have a number of files that contain lists with entries like
-1:-- Applying a replacement map to characters in emacs (Post)--L0--C0--January 11, 2021 12:00 AM

Protesilaos Stavrou: Modus themes: review of select “faint” colours

The Modus themes come with a customisation option to tweak the looks of programming modes (there are lots of customisation options—consult the official manual): modus-themes-syntax 'faint. The present entry documents the refinements that were introduced to a subset of those “faint” colours.

In this report I am making use of the new color-tools.el library developed by Github user neeasade. Even though it is not available in any package archive as of this writing, I highly recommend it to every Emacs user who has an interest in colour and/or who is a theme designer. Consider it as a complement to the built-in color.el Emacs library (check the source code with M-x find-library and then insert color). What it offers compared to the built-in option is an element of convenience, as it lets us use the colour space of our choice. In my case that is sRGB while the notation is hexadecimal.

Colour enthusiasts are also encouraged to read neeasade’s essay: Reasoning about colors.

The color-tools function that introduces a new test to my workflow is ct-name-distance, which applies the CIE ΔE 2000 formula. For the purposes of this article, I am also applying ct-contrast-ratio, even though there exists modus-themes-contrast as part of my themes, which builds on the same WCAG formula for contrast in relative luminance between two values (implemented in modus-themes-wcag-formula).

Old and new values for “faint” blues and magentas

The tables below merely present the affected variables and the change in values assigned to them. The overall intent is to slightly increase the saturation of those colours while accounting for differences between them in lieu of their intended purpose, which is to highlight code in a more subtle way than the default aesthetic of the themes—read the doc string of modus-themes-syntax.

cyan-faint and cyan-alt-other-faint for Modus Operandi have also been corrected for hueness, mainly by reducing their red light channel. Other changes are more subtle.

#+DESCRIPTION: Affected values for Modus Operandi
| Internal name           | Old     | New     |
|-------------------------+---------+---------|
| cyan-faint              | #12506f | #005077 |
| cyan-alt-other-faint    | #2e584f | #125458 |
| blue-faint              | #002f88 | #003497 |
| blue-alt-faint          | #003f78 | #0f3d8c |
| blue-alt-other-faint    | #1f0f6f | #001087 |
| magenta-alt-faint       | #70256f | #7b206f |
| magenta-alt-other-faint | #5f3f7f | #55348e |

#+DESCRIPTION: Affected values for Modus Vivendi
| Internal name           | Old     | New     |
|-------------------------+---------+---------|
| blue-alt-faint          | #a4b0ff | #a0acf5 |
| blue-alt-other-faint    | #8fc5ff | #87c8ff |
| magenta-alt-other-faint | #d0b4ff | #cfa6ff |

Here is a picture of the same table with M-x rainbow-mode enabled, so if it does not look clear please open it in another window:

Modus themes select faint colours

Notice the fine tweaks (yes, those are the lengths we go to).

Harmonising colour distance for Modus Operandi

The following table only concerns Modus Operandi (we employ another technique for Modus Vivendi—next section). It measures the distance of the new values relative to black and white (CIE ΔE 2000). A value of 100 is the maximum and it would mean in practical terms that the closer our values are to the maximum, the more they appear as variants of black for our light theme.

The table must thus be read as an attempt to slightly “brighten up” those values and/or normalise the distance between some of them. As such compare columns 2 to 4 and 3 to 6 (all tables are in org-mode notation).

#+DESCRIPTION: Modus Operandi cie-DE2000 distance for faint blues and magentas
| old     | #ffffff | #000000 | new     | #ffffff | #000000 |
|---------+---------+---------+---------+---------+---------|
| #12506f |      58 |      27 | #005077 |      58 |      28 |
| #2e584f |      55 |      28 | #125458 |      58 |      27 |
| #002f88 |      71 |      29 | #003497 |      68 |      31 |
| #003f78 |      65 |      27 | #0f3d8c |      65 |      30 |
| #1f0f6f |      83 |      28 | #001087 |      81 |      30 |
| #70256f |      64 |      31 | #7b206f |      62 |      32 |
| #5f3f7f |      59 |      32 | #55348e |      63 |      32 |
#+TBLFM: $2='(ct-name-distance $1 @1$2);%0.0f :: $3='(ct-name-distance $1 @1$3);%0.0f :: $5='(ct-name-distance $4 @1$5);%0.0f :: $6='(ct-name-distance $4 @1$6);%0.0f

[ does anyone know of a more succinct #+TBLFM expression? ]

An interesting observation to make with regard to the innate properties of the channels of light, is how #001087 and its old #1f0f6f (blue-alt-other-faint) is perceived as being closer to black while compared to pure white, even though it is impressed in more-or-less the same way as the other colours when compared to pure black (the discrepancies in the values shown on row 6, relative to the other rows). This is because the blue channel, here represented as pure blue (#0000ff), is the darkest among the three components of the RGB triplet that we are using (green is the brightest, red is medium (though not precisely)).

Color distance between the values of Modus Vivendi

While we tested our colours against black and white for Modus Operandi, that technique was not suitable for Modus Vivendi. This is because a dark theme has different requirements and the reason is that the human eye is more attuned to spot differences in colour against a dark backdrop (and colour is, in essence, an expression of light, while the pure black main background of Modus Vivendi is meant to represent the absence of light—notwithstanding screen technology that always uses light even for black).

As such, we are mostly interested in adjusting the distance between the colour values that were deemed somewhat problematic (always in relative terms, as those tweaks are virtually not discernible by the untrained observer).

#+DESCRIPTION: Modus Vivendi cie-DE2000 distance OLD
|         |         | Distance |
|---------+---------+----------|
| #a4b0ff | #8fc5ff |  10.2885 |
| #8fc5ff | #d0b4ff |  19.9316 |
| #d0b4ff | #a4b0ff |  10.5743 |
#+TBLFM: $3='(ct-name-distance $1 $2);%0.4f

#+DESCRIPTION: Modus Vivendi cie-DE2000 distance NEW
|         |         | Distance |
|---------+---------+----------|
| #a0acf5 | #87c8ff |  13.2249 |
| #87c8ff | #cfa6ff |  24.2411 |
| #cfa6ff | #a0acf5 |  11.7710 |
#+TBLFM: $3='(ct-name-distance $1 $2);%0.4f

Contrast compared to the main (and relevant) background values

For the sake of completeness, the following tables confirm that the new values are consistent with the overarching design principle of the themes for a minimum contrast in relative luminance between background and foreground of 7:1 or higher.

#+DESCRIPTION: Modus Operandi WCAG contrast for select "faint" colours
|         | #ffffff | #f8f8f8 | #f0f0f0 |
|---------+---------+---------+---------|
| #005077 |    8.70 |    8.19 |    7.63 |
| #125458 |    8.63 |    8.12 |    7.57 |
| #003497 |   10.84 |   10.20 |    9.51 |
| #0f3d8c |   10.16 |    9.57 |    8.92 |
| #001087 |   14.75 |   13.89 |   12.94 |
| #7b206f |    9.22 |    8.68 |    8.09 |
| #55348e |    9.26 |    8.72 |    8.12 |
#+TBLFM: $2='(ct-contrast-ratio $1 @1$2);%0.2f :: $3='(ct-contrast-ratio $1 @1$3);%0.2f :: $4='(ct-contrast-ratio $1 @1$4);%0.2f

#+DESCRIPTION: Modus Vivendi WCAG contrast for select "faint" colours
|         | #000000 | #110b11 | #181a20 |
|---------+---------+---------+---------|
| #a0acf5 |    9.71 |    9.00 |    8.05 |
| #87c8ff |   11.74 |   10.87 |    9.72 |
| #cfa6ff |   10.55 |    9.77 |    8.74 |
#+TBLFM: $2='(ct-contrast-ratio $1 @1$2);%0.2f :: $3='(ct-contrast-ratio $1 @1$3);%0.2f :: $4='(ct-contrast-ratio $1 @1$4);%0.2f

As has been noted before, such as in the recent review of the faces that pertain to the rainbow-delimiters package, there are a lot of considerations to be made when designing a theme. My opinion is that this endeavour stands at the intersection of art and science. We employ scientific insight in support of our choices, while we exercise artistic judgement or freedom in interpreting the propriety of every result in its particular context. And we do so in a non-dogmatic way, meaning that we are prepared at all times to review our work and challenge our assumptions.

Consequently and despite the fact that we remain committed to the minimum 7:1 contrast ratio, we cannot tolerate some inadequate technique of procedurally picking colours which conform with a target of that sort, nor can we confine ourselves to arbitrary constraints such as relying only on 4, 8, 16 colours or whatnot. Constraints need be conducive to the primary design objectives and must thus remain subject to continuous interpretation and evaluation, in order to stay in sync with the evolving requirements of the project.

It is the designer who sets the constraints and delineates the boundaries of their artistic discretion, so that there necessarily exists an element of auto-nomy (self-determination) as opposed to hetero-nomy (determined by an other [source]), pursuant to the tenets of the project. The minimum contrast ratio is inviolable, yet there is wide range of scenaria that remains to be tested and carefully examined even after accounting for that principle.

-1:-- Modus themes: review of select “faint” colours (Post)--L0--C0--January 11, 2021 12:00 AM

Andrea: Coverlay for Scala, or how to produce lcov from cobertura

-1:-- Coverlay for Scala, or how to produce lcov from cobertura (Post)--L0--C0--January 11, 2021 12:00 AM

Irreal: Prot on Embark

Protesilaos Stavrou (Prot) has a new video up in which he discusses Embark and some of his extensions to it. For those unfamiliar with Embark, it’s a package that lets you bind actions to keys in a context sensitive way. That is, the action taken for a given key will be different when the point is on a URL from what it will be if it’s on a file name.

The system’s a bit complicated and hard to describe succinctly but Prot demonstrates its major functionality. Of course, being Prot he’s added a few extensions to make it better match his workflow.

The Embark system reminds me a lot of Ivy but as Prot says, the context sensitivity gives it a more focused feel. Watch the video to see what I mean. It’s 33 minutes, 21 seconds so you’ll need to set aside some time but it’s worth taking a look. As usual, Prot provides links to the relevant code so you can see how he has things set up if you want to replicate his workflow and use it as a starting point for your own.

-1:-- Prot on Embark (Post jcs)--L0--C0--January 10, 2021 10:01 PM

Corwin Brust: Overdozing Rx

Do you ever write regular expressions with 71 capture groups, then toss them out? A conversation earlier this evening on IRC reminded me of a thing in want of "talking" about. If you know a bit about dungeon-mode, or aren't that interested in it, you might want to skip ahead or just grab the tests. So, there's this game.. Dungeon is a role-playing game I learned as a kid.
-1:-- Overdozing Rx (Post)--L0--C0--January 10, 2021 06:00 AM

Sacha Chua: Using Emacs to fix automatically generated subtitle timestamps

I like how people are making more and more Emacs-related videos. I think subtitles, transcripts, and show notes would go a long way to helping people quickly search, skim, and squeeze these videos into their day.

Youtube’s automatically-generated subtitles overlap. I think some players scroll the subtitles, but the ones I use just display them in alternating positions. I like to have non-overlapping subtitles, so here’s some code that works with subed.el to fix the timestamps.

(defun my/subed-fix-timestamps ()
  "Change all ending timestamps to the start of the next subtitle."
  (goto-char (point-max))
  (let ((timestamp (subed-subtitle-msecs-start)))
    (while (subed-backward-subtitle-time-start)
      (subed-set-subtitle-time-stop timestamp)
      (setq timestamp (subed-subtitle-msecs-start)))))

Then it’s easy to edit the subtitles (punctuation, capitalization, special terms), especially with the shortcuts for splitting and merging subtitles.

For transcripts with starting and ending timestamps per paragraph, I like using the merge shortcut to merge all the subtitles for a paragraph together. Here’s a sample: https://emacsconf.org/2020/talks/05/

Tonight I edited automatically-generated subtitles for a screencast that was about 40 minutes long. The resulting file had 1157 captions, so about 2 seconds each. I finished it in about 80 minutes, pretty much the 2x speed that I’ve been seeing. I can probably get a little faster if I figure out good workflows for:

  • jumping: avy muscle memory, maybe?
  • splitting things into sentences and phrases
  • fixing common speech recognition errors (ex: emax -> Emacs, which I handle with regex replaces; maybe a list of them?)

I experimented with making a hydra for this before, but thinking about the keys to use slowed me down a bit and it didn’t flow very well. Might be worth tinkering with.

Transcribing from scratch takes me about 4-5x playtime. I haven’t tweaked my workflow for that one yet because I’ve only transcribed one talk with subed.el , and there’s a backlog of talks that already have automatically generated subtitles to edit. Low-hanging fruit! =)

So that’s another thing I (or other people) can occasionally do to help out even if I don’t have enough focused time to think about a programming challenge or do a podcast myself. And I get to learn more in the process, too. Fun!

-1:-- Using Emacs to fix automatically generated subtitle timestamps (Post Sacha Chua)--L0--C0--January 10, 2021 05:59 AM

Irreal: Group Tags in Org-mode

I know about Org’s group tags but like any things in Emacs, I wasn’t using them so they slipped out of my mind. Until today. Today, I saw this Tweet:

and it reminded me that they can be really helpful in some use cases. The documentation for them is here but the TL;DR is that you can assign a set of tags to a group and then search for items with any of the tags by searching for the group name.

You can obviously get along without them but for some applications they’re the perfect solution. Take a look at the documentation to get the full story.

-1:-- Group Tags in Org-mode (Post jcs)--L0--C0--January 09, 2021 08:33 PM

Emacs APAC: Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, January 23, 2021

This month’s Emacs Asia-Pacific (APAC) virtual meetup is scheduled for Saturday, January 23, 2021 with Jitsi Meet and #emacs on Freenode IRC. The timing will be 1400 to 1500 IST. The meetup might get extended by 30 minutes if there is any talk, this page will be updated accordingly. If you would like to give a demo or talk (maximum 20 minutes) on GNU Emacs or any variant, please contact bhavin192 on Freenode with your talk details:
-1:-- Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, January 23, 2021 (Post)--L0--C0--January 09, 2021 12:07 AM

Tory Anderson: Binding keypad numbers for exwm screen shifting

I now have a perfect use for the rarely-used numpad! Because I have three monitors connected and am an exwm/winum user to navigate all those screens from the keyboard, I have bound that rarely-used numpad to quickly allow for switching between screens, up to 9 (I am not sure my brain could handle more than 9 decisions on viewports, anyway…). The magic is that numpad numbers are a different keycodde than the normal numberline at the top of the keyboard.
-1:-- Binding keypad numbers for exwm screen shifting (Post)--L0--C0--January 09, 2021 12:00 AM

Protesilaos Stavrou: Embark and my extras (Emacs)

In this video I provide an overview of Embark’s features. I discuss everything from the basic concepts of acting on targets, to how you can extend it as your front-end for completion candidates. There is also a demonstration of embark-become and how that can be used to make your minibuffer-centric workflows more efficient.

The text of the presentation is copied below (org-mode notation). Refer to my Emacs configuration file (“dotemacs”) for the implementation details: https://protesilaos.com/dotemacs. And check the Git repositories of the projects I covered:


#+TITLE: Emacs: Embark and my extras
#+AUTHOR: Protesilaos Stavrou · protesilaos.com

* Brief introduction to Embark

Embark provides a unified framework of regular Emacs keymaps which let
you carry out /contextually relevant actions/ on *targets* through a common
*point of entry*, typically a /prefix key/.

+ "Actions" are standard Emacs commands, such as =describe-symbol= or some
  interactive command you have defined that reads an argument from the
  minibuffer.

+ "Targets" are semantically sensitive constructs, such as the symbol at
  point, a URL, a file name, the active region, or the current
  completion candidate in the minibuffer (or the completions'
  buffer---more on that in the next section).  Embark has so-called
  "classifiers" which help it determine the category that the target
  belongs to.

+ The "contextually relevant [actions]" are defined in keymaps whose
  scope matches the category of the target.  So =embark-file-map= holds
  all key and command assossiations for when Embark recognises a file
  name as its target.  =embark-region-map= is for actions pertaining to
  the active region; =embark-buffer-map= for buffer names that you access
  through, say, =switch-to-buffer= (=C-x b=).  And so on.

+ As for the "point of entry" or "prefix key", it is an Embark command,
  such as =embark-act=, =embark-act-noexit=, or =embark-become=.  Those
  activate the appropriate keymap, thus granting you access to the
  relevant commands.

Embark can act on individual targets (e.g. the region) or sets of
targets (e.g. the list of minibuffer completion candidates).
* Embark collections and how to cycle completions

Here we will be discussing Embark's ability to act on a set of targets.
Our specific case is to instruct it (via a hook), to automatically
gather the completion candidates of the minibuffer and put them in a
live-updating buffer.  In other words: a front-end to the minibuffer's
underlying completion mechanisms.

Let's test this with =switch-to-buffer= (=C-x b=) and some input that we
provide.  The "Embark Collect" buffer pops up and shows us what we are
currently matching.  We can then produce a snapshot or export this set
to an appropriate major-mode (=ibuffer-mode= in this case).

I received a lot of questions about my workflow with the Embark
completions buffer.  The idea was:

+ How do you select an item when you narrow to a short list?
+ Do you manually switch from the minibuffer to the completions?

The short answer is that I have written some extensions that handle this
"candidate cycling".

The long answer is best illustrated by an example (the following is a
natural cycling behaviour):

+ =C-n= in the minibuffer takes us to the top of the completions' buffer.
+ =C-p= in the minibuffer moves to the completions' bottom.
+ =C-n= inside the completions' buffer moves the line normally or, when at
  the end, switches to the minibuffer.
+ =C-p= inside the completions' buffer also moves the line, though in the
  opposite direction, and when at the top it switches to the minibuffer.

* Perform default action while cycling

A common workflow with Embark is to produce a snapshot of the
minibuffer's collection you have narrowed to and then inspect that
buffer.

Let's try this with =M-x describe-keymap RET embark= (I bind that help to
=C-h K=).  Then we produce a snapshot with =embark-act= (you have a key
binding for that) and =S= for =embark-collect-snapshot=.

In this buffer we can move up and down normally and hit =RET= when we want
to perform the default action which, in this case, is to get a help
buffer for the symbol at point.

With my =C-M-n= or =C-M-p= we essentially combine =C-n= or =C-p= into a single
motion.  This is useful when we want to continue from one line to the
next, such as by inspecting the help buffer of each of those embark
keymaps that we got the snapshot for.

[ this is a concept I got from Ivy's own version of operating on sets of
  targets ]
* Manual previews for Consult commands (consult.el)

Those specific "move+act" motions allow me to get manual previews for
all =consult.el= commands, even though I use the default minibuffer.
Otherwise I would need to use some other library to cycle candidates,
like =icomplete= or =selectrum=.

So here is an example with =consult-line= and purposeful manual previews:

+ Search a file for a pattern
+ Cycle the Embark candidates
+ Use =C-M-j= to "preview" the line at point or, =C-M-n= / =C-M-p= to preview
  the next/previous one and move the point there (the latter two accept
  a numeric argument)

The benefit of this workflow is that I can display a preview only when I
want to and, most importantly, I do it from inside the Embark buffer
instead of the minibuffer (which is why I can avoid Icomplete or
Selectrum).

NOTE: consult can be configured to display previews manually or on a
case-by-case basis, though I feel you only benefit from that if you are
using it with Icomplete or Selectrum.
* A look at ~embark-become~ and cross-package integration

One of my goals with extending Embark for my personal needs is to have
some fluidity or seamlessness while performing minibuffer-centric
actions.  This can be achieved with the =embark-become= command: it lets
you re-use the current minibuffer's input in another minibuffer command.

The default =embark-become= lets you switch contexts between =find-file=
(=C-x C-f=) and =switch-to-buffer= (=C-x b=).  Start either of those actions,
type something, and the invoke =embark-become= to switch to the other (you
should bind =embark-become= to some key---see my dotemacs).

The design of Embark is based on the principle of scoping actions inside
keymaps.  Each of those keymaps applies to a context that Embark can
interpret by reading the category of what is being completed against or
what the target at point is.  Long story short: we can bind our own
actions to keys in each of those contexts and/or we can define our own
keymaps (general or specific) to extend the default options.

What I have here is a work in progress, but consider those two scenaria
with Consult commands for (1) grep and find, (2) outline and line
search:

1. We can invoke the relevant grep command and then decide that what we
   were actually looking for is a find operation.  So we rely on
   =embark-become= to take us from one place to the next without losing
   what we have already inserted in the minibuffer.
2. Same principle for =consult-outline= and =consult-line=, where we may be
   searching for a pattern that exists in a heading only to realise that
   we wanted to query for all lines instead.  =embark-become= to the
   rescue!

* Further information

Refer to my "dotemacs" for the complete setup:
<https://protesilaos.com/dotemacs>.

And check the Git repositories of the projects:

+ <https://github.com/oantolin/embark>
+ <https://github.com/minad/consult>
-1:-- Embark and my extras (Emacs) (Post)--L0--C0--January 09, 2021 12:00 AM

Irreal: Read Meat Friday: A Trojan In Your Editor

Is there a backdoor in your editor? Probably not, even if you’re using IntelliJ, but in a moment of schadenfreude for FOSS folks, the New York Times is reporting that JetBrains software may have been used as vector in the Russian hack.

It’s a good policy not to believe anything you read in the press about technical matters and JetBrains for its part is denying that there’s a backdoor TeamCity—the software in question—but admitted that it’s possible it was exploited somehow to install the trojan. Still, if you’re an IntelliJ user, you’ve got to be wondering what’s in your software.

The problem is, you don’t know because it’s closed source. That’s a problem users of Emacs and other FOSS editors don’t have. It’s easy to minimize the benefits of FOSS because most of us don’t, after all, make changes to—or even read—the source code of most of our applications. And yes, it’s possible for FOSS to be infected too but it’s more difficult and easier to discover.

This episode, whatever its truth, is a useful reminder that having access to the source code of your tools is important. Of course, as Ken Thompson reminds us, that may not be enough, but it’s sure better than using a black box.

-1:-- Read Meat Friday: A Trojan In Your Editor (Post jcs)--L0--C0--January 08, 2021 06:26 PM

tycho garen: Better Company

I've been using company mode, which is a great completion framework for years now, and in genreal, it's phenomenal. For a while, however, I've had the feeling that I'm not getting completion options at exactly the right frequency that I'd like. And a completion framework that's a bit sluggish or that won't offer completions that you'd expect is a drag. I dug in a bit, and got a much better, because of some poor configuration choices I'd made, and I thought I write up my configuration.

Backend Configuration

Company allows for configurable backends, which are just functions that provide completions, many of which are provided in the main company package, but also provided by many third (fourth?) party packages. These backends, then, are in a list which is stored in the company-backends, that company uses to try and find completions. When you get to a moment when you might want to complete things, emacs+company iterate through this list and build a list of expansions. This is pretty straight forward, at least in principle.

Now company is pretty good at making these backends fast, or trying, particularly when the backend might be irrelevant to whatever you're currently editing--except in some special cases--but it means that the order of things in the list matters sometimes. The convention for configuring company backends is to load the module that provides the backend and then push the new backend onto the list. This mostly works fine, but there are some backends that either aren't very fast or have the effect of blocking backends that come later (because they're theoretically applicable to all modes.) These backends to be careful of are: company-yasnippet, company-ispell, and company-dabbrev.

I've never really gotten company-ispell to work (you have to configure a wordlist,) and I've never been a dabbrev user, but I've definitely made the mistake to putting the snippet expansion near the front of the list rather than the end. I've been tweaking things recently, and have settled on the following value for company-backends:

(setq company-backends '(company-capf
                         company-keywords
                         company-semantic
                         company-files
                         company-etags
                         company-elisp
                         company-clang
                         company-irony-c-headers
                         company-irony
                         company-jedi
                         company-cmake
                         company-ispell
                         company-yasnippet))

The main caveat is that everything has to be loaded or have autoloads registered appropriately, particularly for things like jedi (python,) clang, and irony. The "capf" backend is the integration with emacs' default completion-at-point facility, and is the main mechanism by which lap-mode interacts with company, so it's good to keep that at the top.

Make it Fast

I think there's some fear that a completion framework like company could impact the perceived responsiveness of emacs as a whole, and as a result there are a couple of knobs for how to tweak things. Having said that, I've always run things more aggressively, because I like seeing possible completions fast, and I've never seen any real impact on apparent performance or battery utilization. use these settings:

(setq company-tooltip-limit 20)
(setq company-show-numbers t)
(setq company-idle-delay 0)
(setq company-echo-delay 0)

Configure Prompts

To be honest, I mostly like the default popup, but it's nice to be able to look at more completions and spill over to helm when needed. It's a sometimes thing, but it's quite nice:

(use-package helm-company
   :ensure t
   :after (helm company)
   :bind (("C-c C-;" . helm-company))
   :commands (helm-company)
   :init
   (define-key company-mode-map (kbd "C-;") 'helm-company)
   (define-key company-active-map (kbd "C-;") 'helm-company))

Full Configuration

Some of the following is duplicated above, but here's the full configuration that I run with:

(use-package company
  :ensure t
  :delight
  :bind (("C-c ." . company-complete)
         ("C-c C-." . company-complete)
         ("C-c s s" . company-yasnippet)
         :map company-active-map
         ("C-n" . company-select-next)
         ("C-p" . company-select-previous)
         ("C-d" . company-show-doc-buffer)
         ("M-." . company-show-location))
  :init
  (add-hook 'c-mode-common-hook 'company-mode)
  (add-hook 'sgml-mode-hook 'company-mode)
  (add-hook 'emacs-lisp-mode-hook 'company-mode)
  (add-hook 'text-mode-hook 'company-mode)
  (add-hook 'lisp-mode-hook 'company-mode)
  :config
  (eval-after-load 'c-mode
    '(define-key c-mode-map (kbd "[tab]") 'company-complete))

  (setq company-tooltip-limit 20)
  (setq company-show-numbers t)
  (setq company-dabbrev-downcase nil)
  (setq company-idle-delay 0)
  (setq company-echo-delay 0)
  (setq company-ispell-dictionary (f-join tychoish-config-path "aspell-pws"))

  (setq company-backends '(company-capf
                           company-keywords
                           company-semantic
                           company-files
                           company-etags
                           company-elisp
                           company-clang
                           company-irony-c-headers
                           company-irony
                           company-jedi
                           company-cmake
                           company-ispell
                           company-yasnippet))

  (global-company-mode))

(use-package company-quickhelp
  :after company
  :config
  (setq company-quickhelp-idle-delay 0.1)
  (company-quickhelp-mode 1))

(use-package company-irony
  :ensure t
  :after (company irony)
  :commands (company-irony)
  :config
  (add-hook 'irony-mode-hook 'company-irony-setup-begin-commands))

(use-package company-irony-c-headers
  :ensure t
  :commands (company-irony-c-headers)
  :after company-irony)

(use-package company-jedi
  :ensure t
  :commands (company-jedi)
  :after (company python-mode))

(use-package company-statistics
  :ensure t
  :after company
  :config
  (company-statistics-mode))
-1:-- Better Company (Post)--L0--C0--January 08, 2021 12:00 AM

Tory Anderson: Adding a new monitor to my exwm setup

I recently shuffled things with my office and found that I have hardware and ports for a third monitor to connect to my exwm setup. So, without further ado, how to get it going and registered with Linux/EXWM? Discover the new monitor First, I plug my 3rd monitor into my dock. It’s a vga connector, so I get it plugged in and powered up. Ok – upon starting it, I see it has power and that it has a blank black screen (ie without a “not connected” message): it’s physically set up but needs to have the computer send meaningful stuff to it.
-1:-- Adding a new monitor to my exwm setup (Post)--L0--C0--January 08, 2021 12:00 AM

Irreal: The Guile Hacker’s Handbook

Jeremy Korwin has an interesting project underway. He’s writing a Guile hacker’s handbook. Guile, of course, is the official GNU extension language. Korwin’s idea is to document what a beginning Guile hacker needs to know to install, and learn the Guile version of the Scheme language.

An important part of his exposition, so far, is how to configure and use Emacs as a Guile IDE. He suggests using geiser, a Slime-like interface for Scheme. It’s what I use for writing in Scheme and I really like it. It makes the interactive style of programming that I prefer easy and pleasant.

The book is still in its early stages so it’s not really ready for use but it’s interesting to see how it’s evolving.

-1:-- The Guile Hacker’s Handbook (Post jcs)--L0--C0--January 07, 2021 10:32 PM

Andrea: Emacs as your code-compass: how related are these modules?

-1:-- Emacs as your code-compass: how related are these modules? (Post)--L0--C0--January 07, 2021 12:00 AM

Andrea: Cycle everything: why waste does not exist

-1:-- Cycle everything: why waste does not exist (Post)--L0--C0--January 07, 2021 12:00 AM

Ben Simon: Seeing All The Pretty Colors: optimizing emacs + screen + Secure Shell Chrome App

The Secure Shell Chrome App combined with a remote Linux box, screen and emacs is a game-changer. Among other things, it turns my Chromebook into a programmer friendly hacking environment.

One quirk of this combination is that the color scheme emacs loaded by default was often illegible. I'd typically run M-x customize-themes to pick a better color scheme, but no matter the theme I selected the colors were always harsh and often left text hard to read.

Turns out, there's a quick fix to this issue. The problem and its fix is described here. It boils down to this: the Secure Shell App sets the terminal type to xterm-256color. Emacs supports this terminal type, granting it access to, well, 256 colors. But I'm running screen, and screen morphs that terminal type to screen.term-256color. Emacs doesn't know what to make of this terminal type so it falls back to to 8 color mode.

This becomes clear when I ran M-x list-colors-display.

The following tells emacs that screen's terminal type is one that it knows:

(add-to-list 'term-file-aliases
             '("screen.xterm-256color" . "xterm-256color"))

I added this code to my init.el, restarted and suddenly got access to 256 colors.

Now the default emacs color choices make sense. Such a simple fix, and I didn't even realize I had this problem.

-1:-- Seeing All The Pretty Colors: optimizing emacs + screen + Secure Shell Chrome App (Post Ben Simon (noreply@blogger.com))--L0--C0--January 06, 2021 06:32 PM

Ben Simon: hbo-blogger.el: A Simple Strategy for Editing Blogger posts in emacs

I'm writing this post in emacs. I know that may not seem like a big deal, but trust me, it's a big deal. See: here's a screenshot proving this:

My blog is hosted by Blogger, and with the exception of a bit of command line hacking, I've always edited my posts at blogger.com.

Every few years I look around for an emacs friendly Blogger solution but have never found a fit. That changed when I stumbled over oauth2.el. Using this library, I found that I could trivially make authenticated requests to the Blogger API. While interesting, it wasn't immediately obvious what I could use it for. On one hand, I knew I didn't want to build out a full Blogger emacs interface. On the other, it would be sweet if I could somehow leverage emacs for post editing. And thus, hbo-blogger.el was born.

The hbo in hbo-blogger stands for Half-Baked Opportunistic. In other words, this isn't some finely crafted Blogger emacs library. This is me taking every shortcut I can find to somehow mash emacs and Blogger together. As klugy as this sounds, I'm amazed at how well this all came together.

At it's core: hob-blogger offers two key functions:

  ;; Downloads the latest draft post and loads it into
  ;; an emacs buffer
  (hbo-blogger-edit-latest-draft-post "[your blog's URL]"))

  ;; Saves the current buffer, which is specially named with the
  ;; blog-id and post-id back to Blogger
  (hbo-blogger-save-buffer)

With thest two functions, I can seamlessly take a draft post I've started in Blogger, load it into emacs and continue editing it there. I can then use the hbo-blogger-save-buffer to save my writing back at blogger.com.

To glue this together, I've added a new interactive command to my init.el:

(defun blogbyben-edit-latest-draft-post ()
  (interactive)
  (hbo-blogger-edit-latest-draft-post "http://www.blogbyben.com"))

This allows me to type M-x blogbyben-edit-latest-draft-post and I'm off and running. When this function runs it adds hbo-blogger-save-buffer to the post's after-save-hook. The result: saving a post saves the file locally and pushes the content back to Blogger.

Most of this functionality came together with ease. One big catch: the PATCH functionality promised in the Blogger API only works on published posts. If you look at hbo-blogger.el you'll notice I had to fallback on the more clunky PUT call.

While functional, I can see a number of obvious improvements to this library. It should be trivial to add hbo-blogger-new-draft-post to create an empty draft post via emacs. I'm sure there's a menu library I could leverage to show a list of recent Blogger posts and let me choose one to edit from there. I wrote my code using url-retrieve-synchronously when I almost certainly should be using url-retrieve. Finally, I'm sure I'm committing many a sin with the way I'm loading up post buffers. The hard coded call to web-mode, for example, is almost certainly a no-no.

But even with these limitations, I just composed my first Blogger post in emacs and it was awesome! The whole process Just Worked.

You can grab the code for hbo-blogger.el over at github.com.

-1:-- hbo-blogger.el: A Simple Strategy for Editing Blogger posts in emacs (Post Ben Simon (noreply@blogger.com))--L0--C0--January 06, 2021 05:16 AM

Protesilaos Stavrou: Default Emacs completion and extras

In this video I offer an overview of my current completion framework for Emacs. It consists of a set of modules that are pieced together into a robust system. The centrepiece is the standard minibuffer.

The text of the presentation is available right below (org-mode notation). Refer to my Emacs configuration file (“dotemacs”) for the implementation details of my completion framework and everything else I currently have: https://protesilaos.com/dotemacs.


#+TITLE: Default Emacs completion and extras
#+AUTHOR: Protesilaos Stavrou · protesilaos.com

* Piecing together a completion framework

Today I will talk to you about how I currently handle completion in
Emacs.  The plan is to tour you around the various tools I use; tools
which comprise my system for narrowing down a list of candidates.

My system consists of the following constituents:

+ Default minibuffer (exactly what you get when you run =emacs -Q= from
  the command line).
+ =orderless= completion style, which extends the built-in list of pattern
  matching =completion-styles=.
+ =embark= to visualise the list of completion candidates, as well as
  provide actions on a per-item or per-set basis.
+ =consult= to enhance several minibuffer-centric commands.
+ =marginalia= to provide meta-information to various completion lists.

All of the above are modular tools that are independent of each other
yet can operate in tandem.  One can, for example, use =icomplete= or
=selectrum= instead of the default minibuffer.

* Orderless and the built-in ~partial-completion~

As its name suggests, Orderless matches groups out-of-order.  A "group"
can be one among many styles, including a regular expression, a literal
string, an initialism, and so on.  The styles are configurable, while
the list is comprehensive.

Orderless has a concept of "style dispatchers".  Those are user-defined
single characters that are used as a suffix to each group and assign to
it a particular pattern matching style.  For example, I use the equals
sign to declare that a group should be read as a literal string.

While the built-in =partial-completion= covers the niche of dynamic
completion for certain commands.  A case in point is with the =find-file=
command (=C-x C-f=), where it can expand an abbreviated path =~/.l/s/fo=
into =~/.local/share/fonts=.

* Embark for per-item actions (part 1)

The best way to conceptualise Embark is as a contextual menu.  It lets
you carry out context-dependent actions on targets.

What constitutes a "target" will depend on the case: it can it the
current item in the completion list, the symbol at point, or some URL
right under the cursor.  Your conduit to this mode of operation is the
=embark-act= command, which you should bind to a convenient key (=C-,= in my
case).

Let us try these actions on individual targets:

+ Get help for =embark-act= by placing point over it.
+ Browse https://protesilaos.com/modus-themes with =eww=.  Then save the
  link to the kill-ring and yank from there afterwards.
+ Run =describe-function= and insert some function here.
+ Run =M-x switch-buffers= and then kill a buffer instead of switching to
  it.

Each context is bound to a keymap.  The keymap holds the associations
between key bindings and commands that you may call on the given target.

To learn more about the commands you can use after invoking =embark-act=,
type =C-h= (or set up =which-key=---check my dotemacs for the implementation
details).

[ remember that =C-h= as a suffix to any key chord, is a standard way to
  get a Help buffer for all keys that complete the chord ]

* Embark for per-set actions (part 2)

Other than act on a per-item basis, Embark can operate on entire sets of
targets.  Allow me to introduce this concept with an example: we invoke
=M-x describe-keymap= and then search for "embark" to find all keymaps
that pertain to the various contexts in which Embark can perform
meaningful tasks (I bind that help command to =C-h K=).  Now we use
=embark-occur= to produce a persistent buffer with the list of candidates.
It will still run the default action on each target.

You have also seen Embark's "live occur", but let me formally introduce
it to you.  This is a buffer that is initially linked to an active
minibuffer session.  It gets auto-updated to match the input in the
minibuffer and to narrow the list of candidates accordingly.  So if I
call =M-x switch-buffers= (=C-x b=) and type something, this "live occur"
will show me what the matching buffers are.

Because these are standard buffers, we can store them on the disk and
revisit them in the future.  Use =M-x write-file= (=C-x C-w=).

Embark offers another neat utility: =embark-export=.  It produces a buffer
whose major mode matches the category of the targets: =dired-mode= for
files/directories and =ibuffer-mode= for buffers.  Then you can benefit
from the power of those modes.

This per-set functionality of Embark is what allows us to use the
default minibuffer for all completions.  While we could add =icomplete= or
=selectrum= to the mix, there is no need for such an addition.  Embark
live occur merely shows the candidates that are already there and which
the minibuffer is fully aware of.

* Consult for enhanced minibuffer commands

=consult= has a dual purpose:

1. Enhance existing commands, like =M-x imenu= or =M-x switch-to-buffer=.
2. Provide new functionality, such as =consult-line=, =consult-mark=, and
   asynchronously updating grep/find commands.

What this "enhancement" means depends on the case.  Commands such as
those that navigate lines, get an optional preview.  The likes of
=consult-imenu= offer a concept of filtering per type of input: this is
called "narrowing" in Consult's verbiage and is controlled by a key map.

Let us try some common workflows to witness the synergies between the
modules that comprise my system.

+ Visit a large Org file.  Invoke =consult-outline= and produce a
  persistent buffer out of it with =embark-occur=.  This works as an index
  of buffer positions, a "table of contents" if you will.

+ Call =consult-imenu= and use =consult-narrow= to filter by the type of the
  syntactic constructs.

* Marginalia for completion annotations

Finally we have =marginalia=, which you have already seen in the various
Embark live occur buffers I have put on display.  It enriches completion
candidates with pertinent meta information.

Here are some commands that benefit from such annotations:

+ all =describe-*= commands present the first line of the doc string.

+ =switch-to-buffer= (=C-x b=) documents the buffer's major mode and status,
  as well as its underlying file's path.

+ =find-file= (=C-x C-f=) includes the file size, permissions and date.

You get the idea.

Currently those annotations are decorative, in the sense that you cannot
use them as filter predicates or have something like =orderless= do
perform pattern matching against them.  Still, I find this lightweight
utility to be quite valuable.

* A system I can understand

About a year ago I switched from Ivy to Icomplete.  I wanted to simplify
my setup in order to make sense of it.  Doing so helped me learn some
Elisp, mostly through trial and error, and by relying on Emacs'
introspection utilities.  This reminded me of the value proposition of
modularity: a system of linkable-yet-standalone tools is robust in its
own right, while it can be constructed and deconstructed at will both in
pursuit of utilitarian ends and for educational purposes.

By piecing together a system out of Embark, Consult, Orderless,
Marginalia, the default minibuffer, and my extras, I am in a position to
clearly comprehend what is going on.  This is not knowledge for its own
sake: it has the tangible benefit of equipping me with the means to
extend or otherwise tweak my completion framework so that it aligns with
my expectations.

I thus wish to congratulate the authors of those packages.  We have Omar
Antolín Camarena, who develops =embark= and =orderless=.  While Daniel
Mendler produces =consult= (among others).  While both of them maintain
the =marginalia= library.  I really appreciate what they do: their code is
top-notch, but they also invest a lot of effort in documentation.
Manuals and informative READMEs are of paramount importance in bridging
the gap between developers and users.  You read the instructions and you
learn how the thing works.  Then, once you have the requisite confidence
in your abilities, you can delve into the source code.

Here is my rule of thumb: if a project has good docs, then it shows that
the developer is dedicated and meticulous in their work.  Use that as
your guide when picking software.  I am happy to have done so.

* Further information

Refer to my "dotemacs" for my complete setup:
<https://protesilaos.com/dotemacs>.

And check the Git repositories of all those projects:

+ <https://github.com/minad/consult>
+ <https://github.com/oantolin/embark>
+ <https://github.com/minad/marginalia>
+ <https://github.com/oantolin/orderless>
-1:-- Default Emacs completion and extras (Post)--L0--C0--January 06, 2021 12:00 AM

Irreal: Why You Should Learn Emacs This Year

David Wilson over at the System Crafters YouTube channel is starting off the year with a video that gives you 5 Reasons to Learn Emacs in 2021. He begins by noting that Emacs is not a text editor or at least not just a text editor. That’s not news to Emacs oldtimers, of course. As most of you know by now, I think of Emacs as a sort of lightweight version of a Lisp Machine and the working/development environment that they provided.

Wilson has a Linux laptop so he can run EXWM, which serves as an Emacs based window manager and increases the feeling of running in a Lisp Machine-like environment. All of that is important because it means you can customize your environment to be exactly what you want it to be. The source code is there, the documentation is there and they’re both easily available right from Emacs. There’s no need to be online or to go to an external site.

Wilson also calls out the advantages of Emacs’ keyboard-based UI. You can leave your mouse at home and still have full and easy control of your environment. That is, I suppose, even more true if you’re running EXWM. Of course, if you’re fond of rodents, Emacs supports your mouse just fine.

Finally, there’s Magit and Org-mode. They’re most people’s idea of Emacs’ killer apps and Wilson spends a bit of time on Org and Magit demonstrating a few of their features.

The video is 26 minutes, 38 seconds long so plan accordingly. It’s a nice video and worth spending the half hour on. If you know someone who’s wondering if they should invest in Emacs, this is a good place to point them.

-1:-- Why You Should Learn Emacs This Year (Post jcs)--L0--C0--January 05, 2021 09:18 PM

Sacha Chua: 2021-01-04 Emacs news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

-1:-- 2021-01-04 Emacs news (Post Sacha Chua)--L0--C0--January 05, 2021 06:11 AM

Marcin Borkowski: Current Emacs version

Add a bug warning
-1:-- Current Emacs version (Post)--L0--C0--January 04, 2021 08:43 PM

Marcin Borkowski: Current Emacs commit revisited

Almost four years ago I described a simple command to insert the current Emacs version at point, together with the commit hash taken from the repo. Guess what? A few days ago I found a bug in it.
-1:-- Current Emacs commit revisited (Post)--L0--C0--January 04, 2021 08:40 PM

Corwin Brust: The Automation Begins

The Automation Begins Having decided I should make a blog to chronicle my adventures in Emacs, I started looking into hugo a minimal blogging framework written in GO. It turns out that hugo has excellent org integration, incorporating go-org, which is the same library used by Github. Approach and Setup As pre-work, I created the (sub) domain where this blog is hosted with my web hosting provider's CPANEL tools Then I created a new shell user with access only to the new site and enabled ssh access for the new user.
-1:-- The Automation Begins (Post)--L0--C0--January 04, 2021 05:59 AM

Corwin Brust: Experimenting With Emacs

Experimenting with Emacs A Brief Introduction I'm Corwin, he/him, 5 kids, it's complicated. I'm a 20 year information technology professional, which has me currently supporting financial services digital and interactive marketing in terms of information security/compliance and data services intersections. By day I spend a fair amount of time in Microsoft Visio but I also use Emacs. At home I use Emacs a lot. Our firm allows us to bring our own text editor, and I was able to request get Emacs 26 packaged for simple install by myself and colleagues, thanks for 26.
-1:-- Experimenting With Emacs (Post)--L0--C0--January 04, 2021 02:56 AM

Irreal: REPLs

Mikel Evins has a lovely post that considers interactive programming and REPLs. As many of you know, I love interactive programming and am a huge fan of it. I like how you can try out bits of code and feel your way to larger functions and finally a program. If you’re not familiar with the concept, take a look at this fascinating video from Kris Jenkins as he writes a Spotify client in Elisp right before your eyes.

Evins begins by examining the idea of a REPL and why they aren’t all the same.There is, he says, a big difference between a Lisp or Smalltalk REPL and one provided by, say, Python. You should consult his post for exactly what that difference is but the TL;DR is that the Lisp REPL allows you to talk to your program as it’s running, even if it enters an error state.

He goes on to lament that many—or perhaps most—programmers today have never experienced this sort of programming and may not even know it exists. That’s too bad, he says, because many of them would find that it makes them happier and more efficient. I certainly agree. I always enjoy programming more when I can do it in an interactive way. Of course, that means writing in a Lisp or Smalltalk so it’s not always possible but it’s great when I can.

-1:-- REPLs (Post jcs)--L0--C0--January 03, 2021 09:13 PM

Manuel Uberti: Re-solutions

I’ve been studying philosophy at Ca’ Foscari for about a year and half now, devoting most of my spare time to wonderful and wonderfully difficult books, and enjoying every part of this journey. There is still a lot of ground to cover because I see many gaps to fill and thoughts to process, but there is one thing that I am sure of: it’s going to be the journey of a lifetime.

I’ve not been so deeply fascinated and involved with something in a long while. Ask my wife and she is going to tell you that perhaps my love for cinema can match this passion for philosophy. I could agree, but cinema has not really been on my side lately1. Beside few exceptions2, 2020 will not be remembered for the films or the directors that inspired me to write.

The last days of 2020 were dedicated to planning new year’s resolutions. To be perfectly honest, I am not a great fan of new year’s resolutions. Most of the time I forget about them in a couple of months. To circumvent my poor will, I decided to keep the resolutions simple, small, and practical. This is what I wrote down on my BuJo:

  • More books and less films
  • More philosophy and less fiction
  • Running

The first two are easy to adopt side by side. I watched way too many forgettable films last year, leaving the couch with the horrible feeling of time wasted. I do not want to repeat that. If there isn’t a film to watch, I want to turn off the TV, forget about my Blu-ray collection, and grab the book next to me.

As for the kind of book to pick up, I want to avoid contemporary fiction. There is nothing wrong with contemporary fiction, of course, but most of the contemporary books I read in 2020 proved to be little more than decent entertainment. There is so much to read, and it’s not just philosophy. I want more classics on my bedside table, and I want to read more from authors I love. Consider it a sabbatical. I intend to come back to contemporary fiction next year.

Finally, running. Let’s just say I stopped for no good reason and I am waiting for my contact lens to start again. As simple as this resolution looks, it’s also the most necessary one. Between work and studies the time I spend at my desk has become unhealthy, and I know how fresh air and exercise make me feel.

For all the good things in this planning, I see a couple of drawbacks here. If I manage to stick to these resolutions, computing is going to play a different role in my life. I will still be in front of my Emacs five days a week, but that’s about it. Whereas this means less tinkering and less githubbing, it also means less writing for my blogs. Nevertheless, for the sake of my priorities, I am willing to sacrifice writing just as I am willing to put cinema aside.

Happy new year.

Footnotes

  1. The small number of articles published last year on my other blog, Films in Words, is telling. 

  2. See Films in Words

-1:-- Re-solutions (Post)--L0--C0--January 03, 2021 12:00 AM

Irreal: Tangling Dotfiles From an Org File

Despite the XDG base directory specification, configuration files are still stored all over our file systems. If you have a single machine, maintaining those files is not too much trouble—they’re almost all “set it and forget it”—but when you have multiple machines, especially if you frequently have to setup new machines, it can be a pain. A neat idea for dealing with this is to keep your dotfiles in an Org file and tangle them to their proper place. I wrote about that here and here.

The basic idea is that you put the contents of each config file into an Org source block and then tangle either a single block or all of them to write each config file to its proper place. That allows you to have a single source of truth for your dotfiles and makes setting up new machines—or even just updating a single config file—a snap.

NapoleonWils0n has an excellent video on implementing the idea. He used to keep all his dotfiles in a Git repository but that’s fairly difficult to set up and maintain. His Org based method handles both cases: it writes the dotfiles to their proper places but also builds a file for a Git repository. NapoleonWils0n doesn’t make clear the utility of maintaining a separate Git repository except to say it provides a further backup. Of course, you can put the Org file under version control and be done with it. Still, his process makes it clear how flexible the method is.

The video is 19 minutes, 23 seconds so plan accordingly. There’s a copy of the Org file he uses in his Github repository so don’t worry about trying to take in everything from the video.

-1:-- Tangling Dotfiles From an Org File (Post jcs)--L0--C0--January 02, 2021 06:50 PM