Magnus: Nix shell, direnv and XDG_DATA_DIRS

A few weeks ago I noticed that I no longer could use haskell-hoogle-lookup-from-website in Emacs. After a bit of experimentation I found that the reason was that I couldn't use xdg-open in a Nix shell. Yesterday I finally got around to look into further.

It's caused by direnv overwriting XDG_DATA_DIRS rather than appending to it. Of course someone already reported a bug already.

The workaround is to use

use nix --keep XDG_DATA_DIRS
-1:-- Nix shell, direnv and XDG_DATA_DIRS (Post)--L0--C0--April 13, 2021 06:04 AM

Sacha Chua: Emacs: Making a hydra cheatsheet for Lispy

I wanted to get the hang of Lispy thanks to Leo Vivier’s presentation at EmacsSF, but there are a lot of keyboard shortcuts to explore. In Karl Voit’s demo of Org Mode at GLT21, he showed how he uses Hydra to make cheat sheets. That makes perfect sense, of course, as Hydra can display text and allow you to run commands while the text is displayed. I wanted to make a Hydra that would show me categorized commands to make it easier to look up and eventually remember them. I also wanted to skip the commands that I already knew or that I didn’t want to focus on just yet.

Fortunately, the function reference had a link to the Org file used to generate it. I copied the tables, merged them together, named them with #+NAME: bindings, replaced the links with plain text, and added a third column with the category I wanted to put commands into.

#bindings
key function column
< lispy-barf  
A lispy-beginning-of-defun  
j lispy-down  
Z lispy-edebug-stop  
B lispy-ediff-regions  
G lispy-goto-local  
h lispy-left  
N lispy-narrow  
y lispy-occur  
o lispy-other-mode  
J lispy-outline-next  
K lispy-outline-prev  
P lispy-paste  
l lispy-right  
I lispy-shifttab  
> lispy-slurp  
SPC lispy-space  
xB lispy-store-region-and-buffer  
u lispy-undo  
k lispy-up  
v lispy-view  
V lispy-visit  
W lispy-widen  
D pop-tag-mark  
x see  
L unbound  
U unbound  
X unbound  
Y unbound  
H lispy-ace-symbol-replace Edit
c lispy-clone Edit
C lispy-convolute Edit
n lispy-new-copy Edit
O lispy-oneline Edit
r lispy-raise Edit
R lispy-raise-some Edit
\ lispy-splice Edit
S lispy-stringify Edit
i lispy-tab Edit
xj lispy-debug-step-in Eval
xe lispy-edebug Eval
xT lispy-ert Eval
e lispy-eval Eval
E lispy-eval-and-insert Eval
xr lispy-eval-and-replace Eval
p lispy-eval-other-window Eval
q lispy-ace-paren Move
z lispy-knight Move
s lispy-move-down Move
w lispy-move-up Move
t lispy-teleport Move
Q lispy-ace-char Nav
lispy-ace-subword Nav
a lispy-ace-symbol Nav
b lispy-back Nav
d lispy-different Nav
f lispy-flow Nav
F lispy-follow Nav
g lispy-goto Nav
xb lispy-bind-variable Refactor
xf lispy-flatten Refactor
xc lispy-to-cond Refactor
xd lispy-to-defun Refactor
xi lispy-to-ifs Refactor
xl lispy-to-lambda Refactor
xu lispy-unbind-variable Refactor
M lispy-multiline Other
xh lispy-describe Other
m lispy-mark-list Other

I wrote this Emacs Lisp code with the header arguments #+begin_src emacs-lisp :var bindings=bindings :colnames yes:

(eval
 (append
  '(defhydra my/lispy-cheat-sheet (:hint nil :foreign-keys run)
     ("<f14>" nil :exit t))
  (cl-loop for x in bindings
           unless (string= "" (elt x 2))
           collect
           (list (car x)
                 (intern (elt x 1))
                 (when (string-match "lispy-\\(?:eval-\\)?\\(.+\\)"
                                     (elt x 1))
                   (match-string 1 (elt x 1)))
                 :column
                 (elt x 2)))))
(with-eval-after-load "lispy"
  (define-key lispy-mode-map (kbd "<f14>") 'my/lispy-cheat-sheet/body))

Here’s the result:

Screenshot_20210413_002503.png

Figure 1: Hydra-based cheat sheet

I’m experimenting with having my Windows key be F14 if tapped and Super_L if held down. I use KDE, so I disabled the Applications shortcut with:

kwriteconfig5 --file ~/.config/kwinrc --group ModifierOnlyShortcuts --key Meta ""
qdbus org.kde.KWin /KWin reconfigure

and then used xcape -e 'Super_L=F14' to make it work.

Looking forward to getting the hang of this!

This is part of my Emacs configuration.
-1:-- Emacs: Making a hydra cheatsheet for Lispy (Post Sacha Chua)--L0--C0--April 13, 2021 04:57 AM

Cyberthal: To avoid Emacs pinky, wear fingerless gloves and hit Ctrl with the metacarpal pad.

I can avoid developing Emacs pinky by wearing padded fingerless gloves and hitting Ctrl with the metacarpal base pad instead.  Can work for the adjacent modkey as well.

I'm using a Perixx ergonomic split keyboard sitting on lap, in ergonomic chair.

Using pads works when wrist is extended.  When wrist is flexed, pads don't work as well, but pinky strain is less anyway.

I can operate the two outermost mod keys with pads when wrist is extended, and one when flexed.

-1:-- To avoid Emacs pinky, wear fingerless gloves and hit Ctrl with the metacarpal pad. (Post Cyberthal)--L0--C0--April 12, 2021 07:28 PM

Irreal: Mickey on Native Compilation

As a nice coda to Saturday’s post on native compilation, the incomparable Mickey has his own post on native compilation. As most Emacers know, Mickey is an Emacs expert and his opinions on Emacs matters are always worth paying attention to.

Mickey says that native compilation is a significant step forward that has few downsides. Those “downsides” boil down to a new dependency (libgccjit) and the fact that initial compilation is slow. He adds that even the slow compilation has improved in the last 6 months.

He ends the post with his recipe for compiling the native compilation branch. With the coming merging of that branch into Master, it will be marginally easier. Of course, the feature is still under development so it’s not for the timid but if you don’t mind living on the edge or if you want to compile a second version of Emacs to play around with, it’s pretty easy.

-1:-- Mickey on Native Compilation (Post jcs)--L0--C0--April 12, 2021 07:20 PM

Sacha Chua: 2021-04-12 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-04-12 Emacs news (Post Sacha Chua)--L0--C0--April 12, 2021 04:58 AM

Manuel Uberti: Would Alfred Hitchcock use Emacs?

First you have to excuse the awful title, but a cinephile cannot resist the temptation of an easy reference when the Emacs package he is going to write about is called Vertico.

Daniel Mendler has become such a prolific contributor to our Emacs world. His work with Omar Antolín Camarena and Clemens Radermacher (to name a few!) has been showing me how much can be done with little improvements on Emacs default completion system. Actually, “little” is a bit unfair to them because they have been putting a lot of effort in their packages and contributions. What “little” stands for instead is the amount of code I had to add to my init.el to get a superb completion UI. I combine Vertico with Orderless and I didn’t have to do much beside this after the installation via package.el:

 (require 'orderless)
 (setq completion-styles '(orderless))
 
 (require 'vertico)
 (vertico-mode +1)

Well, to be fair I did something more, like binding vertico-exit-input to C-j and setting orderless-matching-styles to orderless-regexp, plus I am using Daniel’s consult to extend Vertico capabilities, but I guess you see where I am going by now. The combination of small packages makes for a modular system that I can interact with more easily. For instance, Daniel can go berserk and forget about the lovely 500 lines of code limit he set himself to with Vertico. Why should I trust this criminal mind, then? I can switch to Selectrum and keep using Consult and Orderless with it1.

The beauty of Vertico is that it is not about reinventing Emacs completion once again. By sticking to Emacs built-in commands and completion facilities, Vertico succeeds in staying close to the source without losing the chance to improve on it. On the one hand, moving to Vertico means it is up to the user to configure extra niceties. That is what packages like Consult, Orderless, Embark, and Marginalia aim for, but again, the user is in charge of the right setup for their needs, while a solution such as Helm offers a lot of functionalities out of the box. On the other hand, tools such as Helm, Ivy, and Selectrum are more complex than Vertico and may bring in code you do not necessarily need, which is something even Emacs itself doesn’t shy away from2.

I find it amazing that a seemingly simple and yet so central feature in my everyday Emacs such as the completion system has pushed people to create all these amazing packages. It seems to me that Helm has helped pave the way for a more powerful experience when it comes to completion and that by studying Emacs internals carefully one can achieve similar benefits with a different approach. As humble end-users of all this we really are a lucky bunch.

Notes

  1. The irony should be obvious. 

  2. I don’t really need games in my text editor. 

-1:-- Would Alfred Hitchcock use Emacs? (Post)--L0--C0--April 12, 2021 12:00 AM

Alvaro Ramirez: Flat Habits meets org agenda

10 April 2021 Flat Habits meets org agenda

Flat Habits v1.0.2 is out today, with habit-toggling now supported from the streak view.

Flat Habits runs on org, making it a great complement to Emacs and org agenda \o/

flat_agenda.gif

-1:-- Flat Habits meets org agenda (Post)--L0--C0--April 10, 2021 03:45 PM

Irreal: Native Compilation: Ready to Merge

Eli Zaretskii has announced that he expects to merge the new native compilation code into the Master branch next week. This is a significant milestone for a really important feature.

Most of the comments were along the lines of “I’ve been using this feature for months and haven’t had any problems.” A few expressed concerns about some edge cases but I didn’t see any show stoppers. The largest TODO appears to be documentation.

Once it gets merged into Master, we can reasonably expect that it will officially be released with Emacs 28. Perhaps—we can only hope—native compilation will put an end to the “Emacs is slow” snark. But probably not.

-1:-- Native Compilation: Ready to Merge (Post jcs)--L0--C0--April 10, 2021 03:26 PM

Christian Tietze: Funding Open Source Software as a Third Party?

In a Discord chat, we’ve recently talked about how well funding for Blender turned out. At the time of writing, they get $137k per month for development. I cannot say if that’s enough or too little. But it’s not nothing.

Being crowd-funded comes with its perils. Especially with free open-source software like Blender, developers tell that it’s not easy to know which user base to focus on, which UI/UX compromises to make, and how to figure out if the project backers are satisfied with the result.

It’s not trivial when you sell apps, either, but there you at least do know which people to listen to if in doubt: your loyal customers.

We wondered how hard it’d be to set up a successful funding pool for other projects, like Emacs. There’s no clear goal, but there’s a ton of bugs to fix and things to maintain, and a couple extra dollars don’t hurt to make it possible to put in more work and at the same time not starve.

Management of expectations, direction of funds, singling out of developers to support – all that would be extra effort. While there’s a FSF fund, there’s no fund that directs your money towards Emacs development. It could go anywhere, split in many ways. So even the money transfer, which is the easiest part, is not simple in this case. It doesn’t suffice to collect money in a pool and then forward the funds to the FSF. (This set-up is also the prime motivation to even talk about crowd-funding Emacs development: because you can’t already do it properly.)

Now making the money available to the software maintainers requires a platform to manage these people. That’s an extra step that sucks. As if raising funds wouldn’t be hard enough already.

Managing people is not a trivial task, either. What if some Emacs user has enough of the daily shortcomings of the editor, whips up a couple of work-in-progress improvements, but is totally new to the scene? How do you compensate these kinds of efforts? They’re not part of the ‘accepted developer pool’, so they won’t get a share of the funds. Do you even want to compensate contributors that way? Would it turn the FOSS spirit on its head and shift the focus from “how can I make this project better” to “how can I make money from this”?

In the end, I’d imagine that managing expectations of backers would be the easiest part, combined with setting up a way to collect and then forward the money. – Legal implications might prove me wrong quickly. Maybe you need a pro-bono organization as a legal entity to manage and forwards funds correctly. More overhead. But customer expectations could be managed by making clear from the get-go that the pool of funds is not a custom order form for your favorite Emacs feature.

Here’s what I imagine: Backers can leave a vote and tell devs what they are most interested in. But this is not a promise by the devs. It’s a mutual “feeling out”. A telling of needs and wants. It’s by no means intended to bind devs (legally, morally, or otherwise) to implement that stuff. In the spirit of patronage, devs shall receive money and do good deeds and improve the software, but not be forced to fulfill someone else’s wishes. Might even be worth keeping the developers secret to avoid their getting bugged by angry backers.

Is the best case scenario then that this fund attracts hundreds of thousands of dollars per month? Would this create a political problem because now there’s a well-funded “power” that wants to have a say in the development of Emacs, and would there be conflict with the vision of the FSF, and veteran pro-bono Emacs maintainers? I’d be surprised if there would not be any trouble.

So funding open source projects like Emacs as a 3rd party is not an easy task. It’s simple to set up, but it’s by no means a smooth ride to make it work.

The best thing that could happen is if the FSF offered a way to directly fund Emacs development. But that only means the FSF would have to figure out how to split the funds among developers. And their problem would be that there already are a lot of active developers known to the FSF, so this would have to be figured out from the start for everyone involved, lest they create a caste system of paid and unpaid devs. It might be easier when there’s “a lot” of monthly funds to share. But if you only have a single slice of pizza, how many more ways can you cut it before you might as well not bother trying?


Receive Christian’s new posts via email

-1:-- Funding Open Source Software as a Third Party? (Post)--L0--C0--April 10, 2021 08:51 AM

Marcin Borkowski: deactivate-mark

Emacs Lisp has two entities called exactly the same – the deactivate-mark function and the deactivate-mark variable. (This is possible at all because Elisp is is a Lisp-2.) As the name suggests, they both serve the same purpose (or rather a similar one), but there seems to be a subtle difference.
-1:-- deactivate-mark (Post)--L0--C0--April 10, 2021 07:52 AM

Emacs APAC: Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, April 24, 2021

This month’s Emacs Asia-Pacific (APAC) virtual meetup is scheduled for Saturday, April 24, 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 TODO with your talk details:
-1:-- Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, April 24, 2021 (Post)--L0--C0--April 10, 2021 12:06 AM

Sacha Chua: Grabbing the Youtube auto-generated captions is pretty useful when making Emacs News

I’ve been adding Emacs-related videos to my public Emacs News playlist to make it easier to include them when I put together Emacs News every week. I still haven’t had much time to watch things, though. But the code I wrote to convert captions into a table so that they could be used to make notes after a meetup presentation turned out to be handy for Emacs News as well.

Screenshot_20210408_221732.png

Figure 1: With a bit of clicking, Youtube can display translated subtitles and a transcript on the side. I haven’t figured out how to get the transcript translated on Youtube yet.

Screenshot_20210408_221732.png

Figure 2: My Org buffer displays the auto-translated captions, making things easy to skim through.

Then I can jump to sections I’m particularly curious about. Neat!

-1:-- Grabbing the Youtube auto-generated captions is pretty useful when making Emacs News (Post Sacha Chua)--L0--C0--April 09, 2021 03:00 AM

Andrea: Emacs as your code-compass: find hotspots in micro-services!

Find hotspots in groups of projects
-1:-- Emacs as your code-compass: find hotspots in micro-services! (Post)--L0--C0--April 09, 2021 12:00 AM

Irreal: Running a Shell Command from Emacs

Over at Emacs Redux, Bozhidar Batsov has a short post on using Meta+! to run a shell command from the minibuffer. The output can go to various places—see Batsov’s post for the details—but usually what you want is to specify the prefix argument (Ctrl+u Meta+!) so that the output of the command is inserted at point.

It’s a useful command but I hardly ever use it. I’m much more likely to use shell-command-on-region (Meta+|) which pipes the contents of the buffer into a shell command. Analogously to Meta+!, specifying the universal argument will cause the contents of the buffer to replaced by the output of the shell command.

Emacs has so much builtin functionality that you probably won’t use these commands very often but sometimes they’re just what you need.

-1:-- Running a Shell Command from Emacs (Post jcs)--L0--C0--April 08, 2021 10:44 PM

Meta Redux: Meta Reduce 2021.0: Still in Lockdown

I’ve noticed the other day that I haven’t written any blog posts this year.1 This made me sad. Another thing that made is sad is that about a year ago I wrote this lockdown-themed article and very little has changed since then - life is still dominated by the COVID-19 pandemic and we’ve been in and out of lockdowns of various strictness ever since. At least this year we have vaccines and the end of the crisis seems to be in sight. The local authorities are predicting that most of Bulgaria’s population will be vaccinated over the next 3 months and I really hope that’s going to be the case. In the mean time - I’m going slightly madder every day…

I have to admit I haven’t made much progress with my OSS projects since the releases of CIDER 1.0 and RuboCop 1.0. I’m making slow progress on all fronts, but in general I haven’t been particularly happy with myself. Some interesting recent developments worth sharing are:

Over the past few months I’ve been trying to find better ways to support the community around my projects, that’s why I was more focused on documentation and exploring new communication channels, instead of features and fixes. I’ll probably write more on the topic soon, but I can tell you now that I really like Discord and I regret not trying it earlier. It reminds me of the early days of Slack when it was cool and simple.

A couple of days ago the results from the annual “State of Clojure” survey were published and it was nice to see I was mentioned there for my efforts to improve the Clojure tooling ecosystem. Another positive data point from the survey was that 44% of the respondents are using Emacs for Clojure development, despite the slowdown of the work on CIDER and the ever stronger competition from other editors and IDEs. Meta-X forever!

Survey Results

I have some interesting ideas for CIDER, nREPL and friends going forward. Let’s see if I’ll manage to make them a reality. I should probably run a couple of project surveys myself, as I completely dropped the ball on those.

Outside of OSS things have also been relatively quiet on my end:

  • I’ve been having some fun with algorithms and programming puzzles. This helps me feel like a real programmer, even if I don’t do much programming on my day job.
  • I finished reading the Witcher books. I have to say I was quite disappointed by the final couple of books.
  • I’ve been educating myself a bit on blockchain technologies and cryptocurrencies. I’m just curious to learn more on the topic, I don’t plan to invest anything in crypto. It’s too much hype for my taste.
  • I caught up with “The Walking Dead”. The show is getting worse every year.
  • I’ve started to watch the new “Snowpiercer” show, but I didn’t like it. I think the movie was way better.
  • I watched “Zack Snyder’s Justice League” and I have to admit is just as good as it was hyped to be.2 I didn’t even notice that it was 4 hours long.
  • I bought myself a pair of Audioengine A2+ speakers, as I wanted to enjoy better music now that I’m spending so much time at home. My initial impression of them is quite positive.
  • I’ve rediscovered “Counter-Strike” 20 years later. We’ve started playing a bit of CS with my co-workers as a bonding activity. It’s just as fun as it used to be back in high-school. And I’m still the worst player in every team.
  • I’ve also been playing on and off “Rise of the Tomb Raider”, but for some reason I’m not enjoying the game as much as the first one. Still, it’s fun, and I can definitely recommend it to people fond of games like “Uncharted”.

That’s all from me for now. As usual, I have a huge backlog of topics for “Meta Redux” and I hope that I’ll make some progress with it over the months to come. Stay safe, stay strong and keep hacking!

  1. At least not here. I did write a couple of articles over at https://emacsredux.com

  2. For DC fans. For everyone else it’s probably still one very dumb movie. 

-1:-- Meta Reduce 2021.0: Still in Lockdown (Post Bozhidar Batsov)--L0--C0--April 08, 2021 06:53 AM

Grant Rettke: Can you get an unquoted result from Emacs server eval?

Yes. You can do it with server-eval-at instead of emacsclient. It took days too long for me to understand the solution. In honor of that effort, in case someone out there can benefit, I wrote down all of my notes here. Happy Hacking!
-1:-- Can you get an unquoted result from Emacs server eval? (Post grant)--L0--C0--April 08, 2021 06:03 AM

Manuel Uberti: Back to the roots

Last time I left straight for the built-in package.el, a choice I have not had the pleasure to regret so far. Now I am going to reason about a more ambitious change in my Emacs configuration: I am not using use-package any more.

Before answering your concerned why!? let me just say that if you are happy with use-package you should stay with it. By wrapping all the settings to a built-in feature or an external package with use-package you can easily notice what you are doing wrong when tweaking something, while having control over the installation and the loading of your favourite library as well. Despite some unhappiness around the web1, use-package is just a great tool that any serious Emacs hacker should consider when digging deep into their .emacs.d.

As for my choice to move away from it, it all started as an experiment. I wanted to see if I could have the same amount of control and readability over my init.el without an extra package. You see, most of the recent changes to my setup involved trying to rely on Emacs own facilities to answer my needs, and I am glad to say vanilla Emacs has been really a surprise in this regard. My liaisons with project.el and Flymake are nice examples of this.

Removing use-package has meant rethinking the way I install packages, especially if I want my setup to be ready to go any time I upgrade to a newer version of Ubuntu. My solution was adding the packages I use to package-selected-packages and have a check on startup to make sure they are installed. This works very well combined with package-autoremove: if a package is not listed under package-selected-packages, Emacs takes care of the mess.

All the use-package blocks have been replaced with a combination of with-eval-after-load, define-key, and add-hook, which was not as complicated as it might sound, and more often than not was similar to what I had in my days before the use-package takeover. True, I lost the nice readability of use-package with this massive edit. For example, its keywords have the benefit of grouping settings together and clearly indicate when a new group starts, but on the other hand now there is less macro-magic masking package-related operations involved. As a result I have a more detailed insight of what is really going on with my Emacs Lisp. For instance, I have gained a better knowledge of what run-with-idle-timer actually does.

Again, it is a matter of personal preferences. By now the beauty of use-package is well-known in the Emacs world and all the praises are well-deserved. Let me stress it again: use-package makes your configuration simpler to manage and easier to read. Those were the main reasons I switched to it years ago, anyway.

However, if you know what you are doing you can achieve a clean and pleasant init.el with what Emacs already offers. Does it take more effort? Yes, it probably does. Is it really worth it? It’s up to you, mate. Am I just showing off? No, come on, don’t be rude.

Notes

  1. See for instance here or here

-1:-- Back to the roots (Post)--L0--C0--April 08, 2021 12:00 AM

Emacs Redux: Run Shell Commands from the Minibuffer

Today we’re going back to the basics.

I assume most of you know that you can run a shell within Emacs using shell-mode or even a terminal (e.g. ansi-term or vterm). While those are super useful there’s a simpler and faster way to run the occasional shell command via the aptly named command shell-command.

You can invoke shell-command by pressing M-! and you’ll get a minibuffer prompt asking you for the command to run. Type something like ls -l and you’ll the ls command’s output straight in your minibuffer. Simple and sweet!

If the command you type ends in &, it will be executed asynchronously and the output will appear in a dedicated buffer (*Async Shell Command*). This is useful for commands that are going to take a while to complete. There’s also the command async-shell-command (bound to M-&) that always runs shell command asynchronously.

A cool trick with shell-command is to run it with a prefix (C-u M-!) - when you do this the output from the shell command is going to be inserted at point.

One important thing to keep in mind is that the shell command will be executed in the directory (default-directory) of the current buffer. If your current buffer has a remote directory (you’re using TRAMP), the shell command is executed on that remote host. Depending on your perspective that’s either a very useful feature or a somewhat undesirable one.

I have to admit that I use these commands quite rarely, but they are still useful from time to time when I want to check something really quick without switching buffers.

As a reminder - you can also evaluate Emacs Lisp code in the minibuffer.

That’s all I have for you today. Keep hacking!

-1:-- Run Shell Commands from the Minibuffer (Post Bozhidar Batsov)--L0--C0--April 07, 2021 07:14 AM

Sacha Chua: 2021-04-05 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-04-05 Emacs news (Post Sacha Chua)--L0--C0--April 06, 2021 02:22 AM

jao: reading source code is fun

From a recent checkout of the Emacs source code:

;;; desktop.el --- save partial status of Emacs when killed -*- lexical-binding: t -*-

;; Copyright (C) 1993-1995, 1997, 2000-2021 Free Software Foundation,
;; Inc.

;; Author: Morten Welinder <terra@diku.dk>
;; Keywords: convenience
;; Favorite-brand-of-beer: None, I hate beer.

;; This file is part of GNU Emacs.

Mine is Guinness :)

-1:-- reading source code is fun (Post)--L0--C0--April 05, 2021 08:45 PM

Emacs NYC: Monthly Online Meetup—Lightning Talks

Monday, May 3, 2021
7:00 PM

Join us online: meet.jit.si/EmacsNYC
Please join us using your favorite IRC client at #emacsnyc or use webchat.freenode.net to join us online.

This month we are doing lightning talks!

We look forward to any talk you want to give that is Emacs or Emacs adjacent.

We do want to hear everything you have to say, but we will be limiting each talk to 5 minutes and we will be strict about this. If you have more to say please consider talking to us about doing a longer talk next month.

Please sign up here.

If there is additional room and you are interested in speaking we will try to accommodate you as best as possible.

If you would like to speak then or on any other occasion, take a look at this guide.

-1:-- Monthly Online Meetup—Lightning Talks (Post)--L0--C0--April 05, 2021 08:03 PM

Irreal: Reading PDF Files with DocView

Emacs-Elements has a nice demonstration on using Emacs’ DocView to read PDF files. One of the nice things about DocView—as opposed to PDF Tools—is that it can read PS, DVI, Djvu, and ODF files as well as PDF files. The downside, of course, is the way it works. When you open a document with DocView, it uses an external tool to render it as one or more PNG files. That can take a few seconds for a long document but more importantly—for me, at least—is that the PNGs are cached. That makes it speedy to reopen the document but it clutters up your file system unless you manually delete the cache.

The video shows how to configure DocView and integrate it with Bookmarks+ to make it easy to locate and open documents. It turns out that you can use any of three external programs to render PDFs into PNGs and the video has some advice on which to use.

Most of the rest of the video demonstrates how to navigate through a document and do things like extracting a rectangular region. DocView is surprisingly featureful and you can see some of that in the video.

If you can’t get PDF Tools working or don’t want to bother trying, DocView is a builtin solution that works well. Its main deficiency, as compared to PDF Tools, is that you can’t annotate the PDF.

-1:-- Reading PDF Files with DocView (Post jcs)--L0--C0--April 04, 2021 03:44 PM

Andrea: Have you editing to do? Edit a little, edit every day, and let Emacs be your coach!

-1:-- Have you editing to do? Edit a little, edit every day, and let Emacs be your coach! (Post)--L0--C0--April 04, 2021 12:00 AM

Irreal: An Org Workflow

Luca Cambiaghi, a data scientist from Copenhagen, has a post on his Org-mode workflow. He’s got three problems to solve:

  1. He doesn’t know when a particular task needs to be worked on.
  2. He forgets to check on tasks that need his attention
  3. He needs a convenient way of capturing tasks when he’s not at his computer

His post describes how he uses Org (and Drafts) to solve these problems. He also discusses how he uses Beorg to check his tasks when he’s not at his computer.

All Org users will immediately know the answer to the first two problems. It’s a simple matter to add “scheduled” and “deadline” dates to a task so that you will be alerted when to start and when you need to finish a task. Similarly, the Org Agenda will give you a nice list of tasks and let you know when there is a deadline approaching.

If you’re already familiar with Org-mode, the most interesting part of the post is how he manages tasks when he’s out and about. The details are in the post but the TL;DR is that he uses beorg to see his agenda on his iPhone and Drafts to capture tasks when he’s not at his computer.

If you have similar requirements, be sure to take a look at Cambiaghi’s post. You may find some helpful ideas.

-1:-- An Org Workflow (Post jcs)--L0--C0--April 03, 2021 05:37 PM

Tory Anderson: selected for brilliant emacs selections

I just discovered1 selected.el2 and am impressed: it is a perfect example of a simple idea that is enormously powerful. This is the kind of idea that leaves you wondering, “why haven’t I thought of that before?” Part of the simplicity is that you define all your own keys for your own usage. Below is my invocation so far, for things I use often. I’m also trying out the move-text3 script, though it isn’t part of my workflow yet.
-1:-- selected for brilliant emacs selections (Post)--L0--C0--April 03, 2021 12:00 AM

Irreal: Red Meat Friday: Text Editors in Lord of the Rings

If editors were places from Lord of the Rings, what would they be? Kieran Healy has an amusing answer.

My only complaint is that Word is not a text editor. Still, its assigned place is apt.

-1:-- Red Meat Friday: Text Editors in Lord of the Rings (Post jcs)--L0--C0--April 02, 2021 04:15 PM

Sacha Chua: Org Mode: Insert YouTube video with separate captions

I’m playing around with some ideas for making it easier to post a video with its captions on a webpage or in an Org file so that it’s easier to skim or search.

This requires the youtube-dl command. I’m also learning how to use dash.el‘s threading macro, so you’ll need to install that as well if you want to run it.

(require 'dash)

(defun my/msecs-to-timestamp (msecs)
  "Convert MSECS to string in the format HH:MM:SS.MS."
  (concat (format-seconds "%02h:%02m:%02s" (/ msecs 1000))
          "." (format "%03d" (mod msecs 1000))))

(defun my/org-insert-youtube-video-with-transcript (url)
  (interactive "MURL: ")
  (let* ((id (if (string-match "v=\\([^&]+\\)" url) (match-string 1 url) url))
         (temp-file (make-temp-name "org-youtube-"))
         (temp-file-name (concat temp-file ".en.srv1"))
         data)
    (when (and (call-process "youtube-dl" nil nil nil
                             "--write-sub" "--write-auto-sub"  "--no-warnings" "--sub-lang" "en" "--skip-download" "--sub-format" "srv1"
                             "-o" temp-file
                             (format "https://youtube.com/watch?v=%s" id))
               (file-exists-p temp-file-name))
      (insert
       (format "#+begin_export html
<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/%s\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\n#+end_export\n" id)
       "\n"
       (mapconcat (lambda (o)
                    (format "| [[https://youtube.com/watch?v=%s&t=%ss][%s]] | %s |\n"
                            id
                            (dom-attr o 'start)
                            (my/msecs-to-timestamp (* 1000 (string-to-number (dom-attr o 'start))))
                            (->> (dom-text o)
                                 (replace-regexp-in-string "[ \n]+" " ")
                                 (replace-regexp-in-string "&#39;" "'")
                                 (replace-regexp-in-string "&quot;" "\""))))
                  (dom-by-tag (xml-parse-file temp-file-name) 'text)
                  ""))
      (delete-file temp-file-name))))

It makes an embedded Youtube video and a table with captions below it. The Org file doesn’t look too bad, either.

Screenshot_20210401_234956.png

I decided to stick to standard Org syntax so that I can read it in Emacs too. With the current implementation, clicking on the timestamps jumps to that position in the video, but on the Youtube website. I haven’t coded anything fancy like keeping the embedded video at a fixed position, controlling it from the clicks, or highlighting the current position. It’s a start, though!

Here’s the output of running it with my talk from the last EmacsConf.

00:00:00.000 I’m Sacha Chua, and welcome to EmacsConf 2020.
00:00:04.000 To kick things off, here are ten cool things
00:00:07.000 that people have been working on
00:00:08.000 since the conference last year.
00:00:10.000 If you want to follow the links
00:00:11.000 or if you’d like to add something I’ve missed,
00:00:14.000 add them to the collaborative pad
00:00:16.000 if you’re watching this live
00:00:17.000 or check out the EmacsConf wiki page for this talk.

… (omitted for brevity)

This is part of my Emacs configuration.
-1:-- Org Mode: Insert YouTube video with separate captions (Post Sacha Chua)--L0--C0--April 02, 2021 03:43 AM

Irreal: The Interactive Declaration and Modes

Something that every Emacser knows is that learning Emacs is a lifelong journey. Even after years of use, we’re always discovering something new. Marcin ‘mbork’ Borkowski is always discovering new things and, happily, sharing them with the rest of us.

His latest discovery actually is something new. So new it hasn’t been officially released yet. Borkowski, being more courageous than I, doesn’t bother with releases; he simply compiles Master every once in while. The discovery is that the interactive declaration can now take extra arguments that specify which modes the function is valid for.

Functions with such a declaration appear in the describe-mode listing for any of the specified modes and it’s easy to arrange for the function not to be considered for completion when not in one of the specified modes.

Head on over to Borkowski’s post for the full story. He says that it should be in 27.2 but as far as I can tell, it isn’t. It looks as if it will be a helpful addition to the Emacs toolset.

-1:-- The Interactive Declaration and Modes (Post jcs)--L0--C0--April 01, 2021 06:57 PM

Irreal: The Info Index

Being an old time Unix head, I had a hard time warming up to the GNU Info system. I preferred the man pages when they were available and found the info utility hard to use. That’s probably because I was using Vi at the time and the key bindings were unfamiliar. The ironical twist that you had to read the Info manual to learn how to use info didn’t help.

That changed when I started using Emacs and Info became a natural and extraordinarily useful feature. Now I get annoyed when some tool I’m using doesn’t have an Info node. At this point, I’ve been using it for almost a decade and half and am pretty familiar with its ins and outs but Marcin Borkowski (mbork) taught me something new.

It turns out that if you use I instead of i to access the index, Emacs will build a virtual node that that has an entry for every term in the index that matches what you’re searching for. You can see this in action by bringing up the Elisp node and then searching (with I) for car.

That’s pretty useful and mbork has a bit more so be sure to take a look at his post.

-1:-- The Info Index (Post jcs)--L0--C0--March 31, 2021 05:21 PM

Saurabh Kukade: Debouncing & Throttling Explained

Introduction

In this article, we will discuss Debouncing and throttling techniques that can be use to optimize the performance of web app by preventing unnecessary API calls and load on the server. Both this techniques may look similar but they are not, use case scenarios of both them are very different.

Debouncing

What is a debounce?

Deboucing is technique to delay execution of invoked function for specific time duration and if the same function gets invoked again in that time duration then again delay the execution of this newly invoked function for specific time duration by scrapping the previous function call.

In other words, execution of function is delayed until it aggregates the input to function in specified time interval to save the frequent and unnecessary server calls. This can be achieved by passing the actual function to Debouncing function and hence we call it as the function is being debounced.

Lets see the generic debouce function in plain vanilla JavaScript.


const debounce = (invokedFunction, waitingTime) => {
  let timeoutId;

  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeoutId);
      invokedFunction(...args);
    };

    if(timeoutId){
      clearTimeout(timeoutId);
    }
    timeoutId = setTimeout(later, waitingTime);
  };
};

Now here `debounce` is a higher order function which is taking an actual function and waiting time and returning a another function. This is done to have closure on actual function and waiting time and timeoutId.

This debounce function can be use as


var debouncedFunction = debounce(
   () => console.log("Click event triggered"), 1000)

window.addEventListener("click", debouncedFunction);

Whenever user will click on the window, function attached to the event will not be executed instantly. This debounce function will wait for 1 second to listen if this function gets invoke again and if it does not then function will be executed after 1 second or if user clicks again within 1 second then countdown timer gets reset and debounce function will again wait for another 1 second to execute this function by scrapping the previous function call by using clearTimeout function with help of timeoutId of previous function.

Throttling

What is throttling?

Throttling is a technique in which, no matter how many times the user fires the event, the attached function will be executed only once in a given time interval, only the first fire event executed immediately.

Throttling gives us a control over the rate at which function is executed, with this we can optimize the performance of the app by limiting calls per interval.

How exactly this technique behaves:

Suppose we have set time interval of 3 second for throttling, once the function is called for first time it gets executed immediately and timer starts for 3 second, within this waiting time if function is called again then it does not get executed. Next function execution will happen only after 3 second are elapsed. This is how we can control rate of function execution.

But this above explanation is not complete, what if the event is fired at 2nd second and it has not been executed, so will it be execute when timer ends? Answer is Yes! function executes after the timer ends if its been called again in waiting period. The idea of throttling is to execute function once after fixed time interval.

Throttling implementation in plain Javascript:

function throttle(callback, limit) {
  var wait = false;                 // Initially, we're not waiting
  return function () {              // We return a throttled function
    if (!wait) {                    // If we're not waiting
      callback.call();              // Execute users function
      wait = true;                  // Prevent future invocations
      setTimeout(function () {      // After a period of time
	      wait = false;               // And allow future invocations
      }, limit);
    }
  };
}

Conclusion

Debouncing and Throttling are just concepts or techniques can be use for solving specific set of problems, hence they are not provided by JavaScript itself. I am not giving here use case scenarios because I do not wish to limit one’s thinking to just finite set of use cases. This concepts are abstract and can be use to solve problems from various domains.

Intention of writing this article was give you more clearer explanations of this two techniques, for which I struggled a lot to wrap my head around. Criticism is always welcome!

-1:-- Debouncing &amp; Throttling Explained (Post)--L0--C0--March 30, 2021 06:30 PM

Irreal: Deleting Git Branches

Over at Emacs Redux, Bozhidar Batsov has a nice post on deleting Git branches. Batsov says that no one really knows how to do it and those who say they do are lying. That may be ever-so-slightly hyperbolic but probably captures a general truth.

The thing is, the operation is trivial with Magit. Those who are already Magit users probably don’t need any other reasons for using it but the operation is a striking example of how Magit makes using Git easier. It’s a small thing but it’s useful to know how to perform a commonly needed operation. See Batsov’s post for the details. It’s a short post and the process is pretty simple so click on over right now while you’re thinking about it.

-1:-- Deleting Git Branches (Post jcs)--L0--C0--March 30, 2021 06:12 PM

Irreal: A New Version of Mu/Mu4e Is Coming

Dirk-Jan C. Binnema (DJCB), the developer of the mu/mu4e suite, has announced that version 1.6 of the programs are coming. The current stable version, 1.4.X, was released a year ago and since then development has been taking place in the 1.5.X branch. DJCB says that they’ve frozen 1.5 to just bug fixes and documentation so that they can release the new stable version, 1.6.

His announcement includes a links to the version 1.5 News file so you can see what’s coming if you can’t wait to see. At this point, the programs are mature software so the update is basically polishing and small UX improvements. One significant change is that the gnus-based message viewer is now the default, although you can, of course, keep the old viewer if you like. Other than that, the indexing has been improved as has support for S/MIME, faster crypto, syntax highlighting, and calendar invitations.

I’ve been using mu/mu4e since (I think) the 0.9.6 version and have never looked back. It’s easy to organize and read your emails and for those that really depend on HTML, a quick key press will pop them up in EWW or your browser. This is GREAT software and I wouldn’t want to live without it.

-1:-- A New Version of Mu/Mu4e Is Coming (Post jcs)--L0--C0--March 29, 2021 07:14 PM

Emacs APAC: Notes from Emacs Asia-Pacific (APAC) virtual meetup, March 2021

These are the notes from Emacs Asia-Pacific (APAC) meetup happened on March 27, 2021. R studio / R with Emacs, reproducible research https://fosdem.org/2021/schedule/event/open_research_emacs_orgmode/ https://m-x-research.github.io/ Literate configuration / Org babel blocks https://jherrlin.github.io/posts/emacs-orgmode-source-code-blocks/ https://zzamboni.org/post/my-doom-emacs-configuration-with-commentary/ http://howardism.org/Technical/Emacs/literate-devops.html SQL babel blocks (single session for all blocks) https://www.orgmode.org/worg/org-contrib/babel/languages/ob-doc-sql.html https://www.emacswiki.org/emacs/SqlMode https://www.youtube.com/watch?v=CGnt_PWoM5Y Doom Emacs on Windows https://www.reddit.com/r/emacs/comments/m7pe6c/wsl2emacsvcxsrv_open_everything_with_native/ https://www.youtube.com/watch?v=3qDoHd-6NOQ Personal wiki based on Org
-1:-- Notes from Emacs Asia-Pacific (APAC) virtual meetup, March 2021 (Post)--L0--C0--March 29, 2021 12:59 PM

Sacha Chua: 2021-03-29 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-03-29 Emacs news (Post Sacha Chua)--L0--C0--March 29, 2021 05:01 AM

Irreal: Org Mode 9.4.5 Released

Bastien Guerry tweets that Org 9.4.5 is out:

It’s a bug-fix release so don’t expect any new or changed functionality.

Perhaps more important is the news that after the upcoming Org 9.5, releases will no longer be available on the Org ELPA. Stable version will be available on GNU and non-GNU ELPAs. Also after 9.5, the point releases will be reserved for bug fixes and the whole number releases will be for major releases. You can read about these changes here.

-1:-- Org Mode 9.4.5 Released (Post jcs)--L0--C0--March 28, 2021 07:19 PM

John Stevenson: camcorder.el - Creating Animated Gifs & Videos for Spacemacs

Using animated gifs are a lightweight way to show Emacs in action, as can be seen at Emacs Gifs.

I am creating a workshop on developing Clojure with Spacemacs, so here is a little guide as to how I create animated gifs and videos for this workshop directly from Emacs itself using camcorder.el.

There are several different ways to create animated gifs and so far I have found camcorder.el to be the easiest. This approach has been tested on Ubuntu Linux 16.10.

Why an animated gif rather than video?

Being an image format, animated gifs can be used like any other image. So they are easy to include in websites. They will also play continually without any additional code.

Animated gifs are typically smaller in size, so are quicker to download than video and use less resources too.

Some small amount of quality is lost when converting to an animated gif. However, using the optimised and hence slower conversion gives a reasonable quality. I am still experimenting with the setting though to see if I can make the conversion better.

camcorder.el

camcorder.el enables you to create a screen capture specifically of Emacs. When run, a new Emacs frame is created with the contents of the current buffer and your actions in that frame are recorded as a video.

Then camcorder.el can convert the video to an animated gif.

Requirements for camcorder.el

The camcorder.el package itself does not actually do the recording or even the converting, its simply a convienient way to manage other tools without having to leave Emacs.

For a quick and simple conversion from video to animated gif you can select ffmpeg. If you want to optimise the size of the resulting animated gif then select the combination of mplayer and imagemagick.

1
sudo apt-get install recordmydesktop mplayer imagemagick

Add camcorder to Spacemacs

As far as I am aware there is not yet a Spacemacs layer that includes camcorder.el. So instead we add camcorder.el as an additional package.

Edit your ~/.spacemacs configuration file and find dotspacemacs-additional-packages. Then add camcorder to that list of packages:

1
dotspacemacs-additional-packages '(camcorder)

You will need to either reload your Spacemacs configuration with SPC f e R or restart Emacs.

Capturing with camcorder

Run either camcorder-record or camcorder-mode to record Emacs. You are first prompted to give the file name of the video output (ogv video format).

Once you have specified the video name, a 3 second countdown will run before starting the recording.

Command Description
M-x camcorder-record Open a new Emacs frame and record
M-x camcorder-mode Record current Emacs frame
F11 Toggle pause pause
F12 Stop recording and save video

Screencasts are generated in ogv format, although if you hack camcorder.el you could change the video format used and even the video capture tool (recordmydesktop).

As capturing creates a video file, you can edit that file with tools such as OpenShot or Blender video editors. So if you make a small error or want to shorten (or lengthen) a part of the video, then edit it before you convert it to gif.

Converting with camcorder

You can convert the videos you generated during capturing, or any other supported video type. So you can also used camcorder.el if you recorded Emacs (or other tools) separately.

Run the M-x camcorder-convert-to-gif and you are prompted for the video file to convert to an animated gif.

Spacemacs - camcorder - convert-to-gif

Tweaking camcorder.el

I initially made one tweak to camcorder.el, to change the size of the frame created for the capture. I fount the frame too small to work with on a high resolution monitor. The only challenge with this is it creates a larger file for the animated gif.

I changed the height from 20 to 32 and the width from 65 to 120. These sizes provided more space to see the Spacemacs menu as I demonstrate features. When creating screen captures I run my desktop at a resolution of 1360x768 and a Spacemacs font size of 16 (Ubuntu Mono).

1
2
3
4
5
6
7
8
(defcustom frame-parameters
'((name . "camcorder.el Recording - F12 to Stop - F11 to Pause/Resume")
(height . 32)
(width . 120)
(top . 80))
"Parameters used on the recording frame.
See `make-frame'."
:type '(alist :key-type symbol :value-type sexp))

After some testing I have now reverted back to the original height of 20 and width of 32. I have also reduced the font settings in Spacemacs to us Ubuntu Mono with a font size of 12.

In Summary

The package camcorder.el provides a simple 2-step process to create animated gif images of Emacs demos. You can tweak the script easily and can also use different tools to do the screen capture.

Animated gifs are very easy to distribute, especially on web pages and github pages sites. With this process you also have a video version of the demo too.

Keeping your demos short, between 10 and 20 seconds, typically makes the animated gifs easy to follow. So think about what the most important point you are trying to convey when you are creating a new animated gif.

-1:-- camcorder.el - Creating Animated Gifs &amp; Videos for Spacemacs (Post)--L0--C0--March 27, 2021 10:58 AM

John Stevenson: Kanban in Emacs Org-Mode to Get More Work Done

A Kanban board is a way to visualise your work and help you get more work done. You organise your work into tasks that need completeing and use the board to show the state of each card. Kanban encourages you to get work finished before starting new work.

The amazing Emacs Org-mode can be used to create a very fast and easy to use Kanban board that is with you where ever you are.

Update: Using Org-mode doesnt give me everything I want from a Kanban board, but it was an interesting exersice. For now, I am just sticking to my list view of a Kanban board.

Org-mode is built into Emacs / Spacemacs so there is no need to install any packages or layers for any of the following.

Designing a kanban board

The columns on your kanban board represent the state of work and represent your typical workflow. You can represent the states as the most generic todo, doing, done workflow, or anything more specific that adds value to how you manage work.

I have been using kanban for a while, so I am using a five stage workflow: planning, in progress, blocked, review, done

  • planning - work I’d like to do that needs organising so I can do it.
  • in progress - what I am currently working on. I try and keep this to a minimum so I get things done
  • blocked - things I’ve started working on but currently arent able to complete
  • review - work I have completed. Check if there are any follow on tasks or lessons learnt
  • done - things I have completed. Gives feeling of satisfaction

Creating Org-mode stages

Its easy to create your own Org-mode stages, to represent the state of work in your Kanban board. Please see my earlier article on Configuring Emacs Org-Mode to Managing Your Tasks

Create an Org-mode file

Create a new file by opening a new buffer M-x find-files and type in the new file name, ending in .org. Any files with a .org filename extension will automatically set the Emacs major mode to Org-mode.

I use a file called kanban.org for my kanban board.

Spacemacs Emacs
SPC f f C-x C-f
M-x spacemacs/helm-find-files M-x find-files

Create a kanban board

Lets assume you created a file called kanban.org. Edit this file and create a table for the kanban board. You can start creating ths manually by typing | for the table layout or use M-x org-table-create and enter the number of columns and rows for the table. For example, to create for a table with 5 columns and 3 rows, you would speciify 5x3

Add the names of the kanban board in the first row of the table. If you did not use M-x org-table-create then add a header row with M-x org-table-insert-hline.

In my kanban board, this gives

Emacs Org-mode table as Kanban board

Adding tasks to the kanban board

Each item on the board represents a task and we use the Org-mode interal link to jump from the board to the details of the task. To create a link of the same name as the task, simply type the name inside double square brakets [[]].

Emacs Org-mode table as Kanban board - task entry

Moving the tasks across the board

Its easy enough to move the columns around with Alt - <arrow-keys> in org-mode, but there is not a single keybinding to move a cell.

To move the individual tasks between the columns use selective cut and paste:

  • Move the cursor to the cell you want to move and use C-c C-x C-w
  • Use TAB to move to the new cell
  • Paste/Yank the value into the new cell using C-c C-x C-y

However, simply moving the task does not update the Org-mode stage. As each task is a link, I can click on that link and I am taken to the task and can easily update the task stage to match the board.

It would be great if moving the tasks on the board updated the associated task stage and vice versa.

El Kanban - updating the board from task stage changes

I found the El Kanban package that will updated the kanban board based on the task org-mode stages. This uses the Org-mode table format directive that you run each time you want to update the board.

I installed this package and it did pull in my custom org-mode stages for the headers. Unfortunately it did not pull in the tasks to the board, so I will either need to fix the package or find another solution.

Any suggestions are more than welcome.

References

Thank you.
@jr0cket

-1:-- Kanban in Emacs Org-Mode to Get More Work Done (Post)--L0--C0--March 27, 2021 10:58 AM

John Stevenson: Spacemacs - Adding Custom Snippets to Yasnippet

Using yasnippet saves time by avoiding the need to write boilerplate code and minimising other commonly typed content. YASnippet contains mode-specific snippets that expand to anything from a simple text replacement to a code block structure that allows you to skip through parameters and other sections of the code block. See YASnippet in action in this Emacs Yasnippet video.

To use a specific snippet simply type the alias and press M-/. For example, in html-mode typing div and pressing M-/ expands to <div id="▮" class="▯">▯</div> and places the cursor so you can type in the id name, then TAB to the class name, finally TAB to the contents of the div.

You can also combine yasnippets with autocompletion select snippets from the autocompletion menu.

Spacemacs has lots of snippets for most of the languages and modes it supports. However, YASnippets also uses a simple template system in plain text, so its pretty easy to learn. Lets look at how to add your own snippets with Spacemacs.

In regular Emacs, yasnippets expand funciton is usually bound to TAB, but that key is used already in Spacemacs so M-/ is used instead.
If you just want text replacement you can also use Emacs Abbrev mode.

Adding your private snippets to Spacemacs

The easiest place to add your own snippet definitions is in the ~/.emacs.d/private/snippets directory. Under this directory structure you should create a folder named after the relevant mode for your snippets, eg markdown-mode. Inside this mode folder, create files whos names are based on the snippet alias you wish.

So for a work in progress snipped called wip in markdown mode I created ~/.emacs.d/private/snippets/markdown-mode/wip file.

You need to load this new snippet into Spacemacs by either restarting or using the command M-x yas-load-snippet-buffer command in the buffer of the new snippet you have just written. Ths snippet with then work within any markdown mode buffer.

Managing your snippets

Although the private snippets directory is easy to use, it is not under version control. So although its not over-riddend by Spacemacs it also means your private snippets are not backed up anywhere.

If you use the ~/.spacemacs.d/snippets/modename-mode/ directory structure for your snippets then you can version them with Git or similar versioning tools.

How to write a snippet

Typically each snippet template is contained in its own file, named after the alias of the snippet. So a snippet called wip will be in a filename wip, in a directory named after the relevant Emacs mode.

The basic structure of a snippet template is:

1
2
3
4
5
#key : the name of the snippet you type
#name : A description of the snippet (this shows in autocompletion menu too)
#contributor: John Stevenson <john@jr0cket.co.uk>
# --
Add the content you want to replace the snippet name with when it expands

The content can be anything, simple text or more usefully a code strucuture with placeholders for tab stops. You can even include Emacs lisp (elisp) code in there too.

Example: Simple text replacement

I use markdown mode for writing a lot of content, especially for technical workshops. As I am developing these workshops its useful to highlight which sections are still work in progress. Rather than type the common message I use, I’ve created a simple snippet called wip.

1
2
3
4
5
#key : wip
#name : WorkInProgress
#contributor: John Stevenson <john@jr0cket.co.uk>
# --
> **Fixme** work in progress

When you expand this snippet with M-/ then the snippet name is replaced by the content.

Example: Using tab stops

Lets look at an existing snippet called form in the html-mode. This expands into a html form, but also helps you jump from method, id, action and content.

1
2
3
4
5
6
#contributor : Jimmy Wu <frozenthrone88@gmail.com>
#name :<form method="..." id="..." action="..."></form>
# --
<form method="$1" id="$2" action="$3">
$0
</form>

This snippet is the same as the simpler example, except we have added tab stops using the $ sign and a number. When you expand this snippet, the snippet name is replaced by the content as usual but the cursor is placed at the first tab stop $1. Each time you press TAB you move to the next tab stop.

$0 is our exit point from the snippet, so pressing TAB reverts to the usual behaviour outside of YASnippet.

Creating a snippet from existing text

A really fast way of creating a new snippet is to use a finished version of what you would like the snippet to expand to. For a simple text replacement you just hightlight all the text and call helm-yas-create-snippet-on-region, save the snippet and you are done.

For a code structure with tab stops, simply hightlhght a completed code stucture, call helm-yas-create-snippet-on-region and edit the body of your snippet to replace the specific names and values with tab stop placeholders, $1 $2, $3, etc.

Example: Create a simple text replacement

When I write blogs I include a image thumbnail that gives a visual clue as to the topic of the article. Rather than type this in I created a snippet.

First I mark the text I want my new snippet to expand too, in this example: {% img img-thumbnail /images/spacemacs.png %} .

Then I call the function helm-yas-create-snippet-on-region. This prompts me for the mode for the snippet, in this case markdown-mode, then prompts for the location for the snippet file, ~/.emacs/private/snippets/markdown-mode/imgtmb-spacemacs. A new buffer is created with my snippet already filled in.

1
2
3
4
5
6
7
# -*- mode: snippet -*-
#name : imgtmb-spacemacs
#key : imgtmb-spacemacs
#contributor : jr0cket
# --
{% img img-thumbnail /images/spacemacs.png %}

The new snippet buffer already has the name and key values populated from the filename I gave for the snippet, imgtmb-spacemacs. The snippet body is also populated automatically from the text I had highlighted. So all I need to do is save the new snippet and try it out.

Testing your snippets

Once you have written your snippet, you can quickly test it using M-x yas-tryout-snippet. This opens a new empty buffer in the appropriate major mode and inserts the snippet so you can then test it with M-/.

If you just want to try the snippet in an existing buffer, then use M-x yas-load-snippet-buffer to load this new snippet into the correct mode. M-x yas-load-snippet-buffer does exactly the same except it kills the snippet buffer (prompting to save first if neccessary).

There are no default keybindings for these commands in Spacemacs, so you could create a binding under C-o, for example C-o C-s t to try a snippet and C-o C-s l to load a snippet.

Adding yas-snippets to autocompletion in Spacemacs

By adding the autocompletion layer in Spacemacs the YASnippets can be shown in the autocompletion menu as you type.

By default, snippets are not shown in the auto-completion popup, so set the variable auto-completion-enable-snippets-in-popup to t.

1
2
3
(setq-default dotspacemacs-configuration-layers
'((auto-completion :variables
auto-completion-enable-snippets-in-popup t)))

Summary

Find out more about YASnippets and autocompletion from the Github repository for Spacemacs autocompletion layer.

For more details and examples on writing your own snipplets, take a look at:

Thank you.
@jr0cket

-1:-- Spacemacs - Adding Custom Snippets to Yasnippet (Post)--L0--C0--March 27, 2021 10:58 AM

John Stevenson: YASnippets for Faster Clojure Coding

Using snippets saves you time typing common coding structures and helps you avoid silly typos too. Simply typing in a snippet name and pressing M-/ or using M-x yas-expand gives you the full text & code structure from the snippet template.

For example, if you are defining a new function in Clojure then type defn and press M-/ to expand to the full definition structure, including all parens. Then use TAB to move through the structure to complete the name, doc-string, arguments and behaviour of the function.

Lets look at the built-in snippets that come with the Clojure layer in Spacemacs (and should be the default in Emacs YASnippet package).

Its easy to wrtie your own snippets for Clojure or any other language you use with Spacemacs / Emacs

Where do Snippets fit in

There are several ways to speed up typing your Clojure code, Leiningen Templates, autocompletion, clj-refactor and YASnippets.

Snippets are a great way to create much of the common code structures you typically write as you are developing your code. The snippets I use the most are defn, let, ifl and for.

Some of the snippets are made redundant by other Clojure layer features in Spacemacs. For example, when I create a new file then the namespace is automatically added, so I rarely use the ns snippet. I also use clj-refactor which takes care of adding require statements for me, so the require snippet is rarely used.

Note: Smartparens does not work when you are completing an expanded snippet the first time. However, as soon as you tab out of the end of the snippet then smartparens works again. I havent determined if this is simply a missing config or some conflict between YASnippets & Smartparens.

Default snippets for Clojure

The snippets that are available in Spacemacs can be found in the yasnippet github repository or in the ~/.emacs.d/elpa/yasnippet-20160501.1841/snippets/clojure-mode directory on your laptop (when yasnippet package is updated then name of that directory will change).

All the current snippets for Clojure mode are in the following table, indicating which tab stops they have.

Snippet Description Tab Stops
bench benchmark an expression, using the time function body
bp depreciated: break point in swank
def def expression N/A
defm defmacro expression, with name, doc-string, arguments & body tabstops name, docstring, args, body
defn defn expression, with name, doc-string, arguments & body tabstops name, docstring, args, body
defr defrecord docstring, object, args, body
deft deftype docstring, object, args, body
doseq doseq name, body
fn fn - anonymous function name, body
for for condition, body
if if condition, body
ifl if-let - if true, bind a local name binding, body
import import java library library name
is is - clojure test assertion value, expected
let let - bind a local name to a value name, value, body
map map fn, col, col
map.lambda map with anonymous function #() fn, body
mdoc metadata docstring docstring
ns ns - expression with the current namespace inserted automatically N/A
opts destructuring a map with :keys, :or for default values, :as for entire vector :key binding, or defaults, :as binding
pr prn - print function string/value
print println - print function string/value
reduce reduce - reduce expression with an anonymous function args, body
require :require expression with library and alias library, alias
test deftest expression test description, value/expected
try try & catch expression try expression, exception name, body
use depreciated: use require instead
when when when expression, body
whenl when-let - local binding on when condition binding, body

Hint: The above table was created in Emacs markdown mode by enabling the minor mode: orgtbl-mode. Start the table with a | character followed by a word and use TAB to create and align the table as you go through. If you already have content, use the function orgtbl-create-or-convert-from-region. To enable orgtbl-mode by default when in markdown major mode, edit your ~/.spacemacs file, in the dotspacemacs/user section add the line (add-hook 'markdown-mode-hook 'turn-on-orgtbl).

Hope you have fun speeding up the writing of your Clojure code (and any other common text) in Spacemacs / Emacs.

Thank you.
@jr0cket

-1:-- YASnippets for Faster Clojure Coding (Post)--L0--C0--March 27, 2021 10:58 AM

John Stevenson: Using Github Gists From Spacemacs

Github Gists are really useful when you want to share a piece of code or configuration without setting up a version control project. Rather than copy & paste into a Github Gists website, you can create a Gist from any Spacemacs buffer with a single command.

All you need is to add the github layer to your ~/.spacemacs configuration file and reload your configuration M-m f e R or restart Spacemacs. Lets see just how easy it is to use Gists with Spacemacs.

You can also use gist.el with your own Emacs configuration

Connecting to your Github account

When you first run any of the Gist or Github commands you will be prompted for your username, password and 2Factor code. The Gist.el code will create a personal access token on your Github account, avoiding the need to prompt for your Github login details each time.

If you are prompted to enter your personal access token in Emacs, then visit your Github profile page and view the personal acccess tokens section. Edit the token named git.el and regenerated the token. This will take you back to the personal access tokens page and display the new token for git.el. Copy this token into the [github] section of your ~/.gitconfig as follows

1
2
3
[github]
user = jr0cket
oauth-token = thisishweretherealtokenshouldbepasted

If git.el adds a password line to the [github] section of your ~/.gitconfig you should remove that password line. These Github actions only require your username and token.

Creating a Gist from Spacemacs

The current buffer can be copied into a Github Gist using the command M-x gist-buffer.

Gist - create a Gist from the current buffer

You can also create a gist just from a selected region of the buffer. First select the region using C-SPC and run the command M-x gist-region.

If this is the first time using Github from Spacemacs, you will be prompted for your Github username & password. If you have already used Github from Spacemacs, then your account details will have been saved so you do not need to enter them each time.

Keyboard shortcuts

  • M-m g g b : create a public gist from the current Spacemacs buffer
  • M-m g g B : create a private gist from the current Spacemacs buffer
  • M-m g g r : create a public gist from the highlighted region
  • M-m g g R : create a private gist from the highlighted region
  • M-m g g l : list all gists on your github account

Replace M-m with SPC if you are using Spacemacs evil mode

Updating a Gist

When you create a Gist from a buffer there is no direct link between your buffer and the Gist. So if you make changes to your buffer you want to share, you can generate a new gist using M-x gist-buffer & delete the original one (see listing & managing gists below).

Alternatively, once you have created a Gist, you can open that Gist in a buffer and make changes. When you save your changes in the Gist buffer, C-x C-s, the gist on gist.github.com is updated.

Listing & managing Gists

Use the command M-x gist-list or keybinding M-m g g l to show a list of your current Gists.

Spacemacs - Gist list

In the buffer containing the list of your gists, you can use the following commands

  • RETURN : opens the gist in a new buffer
  • g : reload the gist list from server
  • e : edit the gist description, so you know what this gist is about
  • k : delete current gist
  • b : opens the gist in the current web browser
  • y : show current gist url & copies it into the clipboard
  • * : star gist (stars do not show in gist list, only when browsing them on github)
  • ^ : unstar gist
  • f : fork gist - create a copy of your gist on gist.github.com
  • + : add a file to the current gist, creating an additional snippet on the gist
  • - : remove a file from the current gist

Creating Gists from files

If you open a dired buffer you can make gists from marked files, m, by pressing @. This will make a public gist out of marked files (or if you use with a prefix, it will make private gists)

Gist - create a gist from the marked files in dired

Summary

Its really easy to share code and configuration with Github Gists. Its even easier when you use Spacemacs) to create and manages gists for you. Have fun sharing your code & configurations with others via gists.

Thank you.
@jr0cket

-1:-- Using Github Gists From Spacemacs (Post)--L0--C0--March 27, 2021 10:58 AM