## 2020-12-14 Emacs news

|

I’m curious about how we can help Emacs folks find jobs or freelancing contracts by connecting with each other. I don’t really know how it might work out yet, but if you’re looking for someone to fill a position or take on a freelancing contract, would you consider e-mailing me at sacha@sachachua.com so that I can include it in Emacs News? What kind of info might be useful? Short description, contact info, location/remote, and whether the position is free-software-compatible? Let’s figure out what’s possible! =)

## Editing subtitles in Emacs with subed, with synchronized video playback through mpv

Posted: - Modified: | emacs

I’ve been adding subtitles to the talks from EmacsConf 2020, taking advantage of the text that was helpfully autogenerated when I uploaded the videos to the EmacsConf channel on YouTube. Today I spent some time figuring out how to add WebVTT support to subed, an Emacs major mode for editing subtitles. It turns out that it’s pretty cool to be able to bring up the relevant segment in the video whenever the text wasn’t clear. Here’s a quick video of it in action. It shows how I can mostly focus on adding punctuation and changing capitalization, checking every so often with mpv via mpv.el. All in all, it took me 24 minutes to edit the subtitles for a 17-minute talk. Whee!

I submitted a pull request to get the .vtt support into subed-mode in case anyone else finds it helpful. I’ve only tested the mpv synchronization so far, and I’m looking forward to exploring its other features.

You can see these particular subtitles on the talk page for Beyond Vim and Emacs: A Scalable UI Paradigm. Enjoy!

Update 2020-12-13: subed-vtt.el has been merged into master, so you’ll get it when you check out subed. Yay!

## Org Mode: Create a quick timestamped note and capture a screenshot

|

I wanted to be able to quickly create timestamped notes and possibly capture a screenshot. Prompting for a value inside an org-capture-template disrupts my screen a little, so maybe this will make it as easy as possible. I could probably do this without going through org-capture-templates, but I wanted to take advantage of the fact that Org Mode will deal with the date tree and finding the right position itself.

(use-package org
:config
'("p" "Podcast log - timestamped" item
(file+olp+datetree "~/orgzly/timestamped.org")
"%<%H:%M:%S,%3N> %^{Note}"
:immediate-finish t)))
(defun my/org-capture-prefill-template (template &rest values)
"Pre-fill TEMPLATE with VALUES."
(setq template (or template (org-capture-get :template)))
(with-temp-buffer
(insert template)
(goto-char (point-min))
(while (re-search-forward
(concat "%\$$" "\$\\(.+\$$\$\\|"
"<\$$[^>\n]+\$$>\\|"
"\$$[tTuUaliAcxkKInfF]\$$\\|"
"\$$:[-a-zA-Z]+\$$\\|"
"\\^\$${\\([^}]*\$$}\\)"
"?\$$[gGtTuUCLp]\$$?\\|"
"%\\\\\$$[1-9][0-9]*\$$"
"\\)") nil t)
(if (car values)
(replace-match (car values) nil t))
(setq values (cdr values)))
(buffer-string)))
(defun my/capture-screenshot (time &optional note)
"Capture screenshot and save it to a file labeled with TIME and NOTE.
Return the filename."
(interactive (list (current-time) (read-string "Note: ")))
(let* ((filename (expand-file-name
(concat "Screenshot_"
(format-time-string "%Y%0m%d_%H%M%S" time)
(if note (concat " " note) "")
".png")
"~/Pictures"))
(cmd (concat "spectacle -b -o "
(shell-quote-argument filename))))
(shell-command cmd)
filename))
(defun my/capture-timestamped-note (time note)
"Disable Helm and capture a quick timestamped note."
(interactive (list (current-time) (read-string "Note: ")))
(entry (org-capture-select-template "p")))
(org-capture-set-plist entry)
(org-capture-get-template)
(org-capture-set-target-location)
(org-capture-put
:template (org-capture-fill-template
(my/org-capture-prefill-template (org-capture-get :template)
(format-time-string "%H:%M:%S,%3N")
note)))
(org-capture-place-template)
(org-capture-finalize)))
(defun my/capture-timestamped-note-with-screenshot (time note)
(interactive (list (current-time) (read-string "Note: ")))
(kill-new (my/capture-screenshot time note))
(my/capture-timestamped-note time note))


Then I can call it with h h n for my/capture-timestamped-note or h h i for my/capture-timestamped-note-with-screenshot via keyboard shortcuts defined elsewhere in my config (see my/key-chord-commands).

## EmacsConf 2020: Emacs News Highlights and a wishlist

Posted: - Modified: |

At EmacsConf 2020, I did a quick summary of Emacs News over the past year or so. The main highlights were:

1. Emacs 27.1: see Mickey Petersen’s notes
2. Performance: see gccemacs and Bringing GNU Emacs to Native Code
3. Modernization: behaviour and appearance;
4. Doom Emacs: see DoomCasts and DistroTube videos
5. Other videos: Protesilaos StavrouMike ZamanskySystem Crafters, and others
6. Org Mode:
• Zettelkasten-based workflows like org-roam
• lots of experiments with appearance
7. Coding: LSP-mode, faster JSON processing
8. Emacs Application Framework (EAF)
9. Virtual meetups
10. The unofficial Emacs User Survey

To prepare this talk, I used the totally unscientific method of reading through the Emacs News entries since the last conference and deciding on the ones that stuck in my brain or that I thought were worth mentioning.

Then I wrote a script, recorded and edited the audio, and collected the screenshots. I used EMMS to insert timestamps as I played back my audio file, generate subtitles, and combine the audio and images using a long ffmpeg command generated from my Org file. It was a pretty cool workflow, and the code’s in the repository linked below. Whenever I needed to adjust the visuals–like when I decided to have quick number slides to help people keep track of where they were in the list–I just added the timestamps and the images, then recompiled my talk. (Recompiled my talk! I still get a kick out of that idea.) The source code for my talk can be found at https://github.com/sachac/emacsconf-2020-emacs-news-highlights .

Conference-wise, I’m tickled pink by the Org code I wrote in order to figure out if all the talks could fit into the schedule if we squeezed them tight enough. I also had lots of fun writing ERC commands that pulled information from submissions.org. I’ve started putting things together in the organizers’ notebook, although I haven’t tested the reorganized code. Next year, I want to figure out how to release videos throughout the day, and maybe handle alternate streams more easily too. Whee!

It’s been a pretty exciting year for Emacs, and I’m looking forward to seeing what people will build now that we have even more things to play with. I have a wishlist in case you want to help out. =)

• Subtitling my talk made me want to get all the EmacsConf talks subtitled too. =) I’ve started working on the files in emacsconf-wiki/2020/subtitles, and it’s pretty cool to see them in action (ex: Leo’s story about becoming a package maintainer). If you want to help edit autogenerated subtitles, you might be able to use these Git instructions to check out the repository, or we can probably coordinate by e-mail.
• I’d love to make all these wonderful posts and tutorials and videos more findable. Not just EmacsConf, but also the wonderful things that cross our radar in EmacsNews. I think the EmacsWiki could be a great way to do that. Imagine if people took the links from Emacs News and organized them under various topic pages (and maybe even in some kind of logical order) so that people could come across them… And when we start organizing the resources that are out there, we can map the things people want to learn (ooh! skill trees!) and then see where the missing pieces are.
• I think virtual meetups are neat, and I hope more people get to go to them or organize them (including topic-based ones). I updated the Usergroups page to list some upcoming events and remove broken links. When I joined the EmacsSF one via Jitsi (despite being nowhere near San Francisco; the joys of connecting online!), they said they even sometimes browse through Emacs News together when they’re looking for something to spark conversation. So if you want to start a usergroup but you aren’t sure if you can line up enough presentations or keep the conversation going, maybe that could work for you too? Anyway, let me know if you have an upcoming meetup and I can add it to the calendar I’ve started putting together.
• Someone mentioned possibly coming up with a fediverse/free-software alternative to reddit.com/r/emacs . Please let me know if that happens so that I can figure out how to pull interesting things from it.
• Lots of people are having a hard time finding work due to COVID-19. I wonder if we can make some kind of job board or freelancing network to help people out. It can go beyond tech, too, since there are lots of people who use Emacs in all sorts of fields. Let me know if you’re looking to hire someone, and maybe we can figure out how to include that in Emacs News or the wiki! (Maybe short description, location/remote, and whether the position is free-software-friendly since that matters to quite a few people?)

So those are a few of the things that I think would be pretty cool, looking ahead. If you’re curious about looking back, here’s my EmacsConf 2019 community update too. That one covered the time between EmacsConf 2014 and EmacsConf 2019. It’s pretty amazing to see how far we’ve come, and I can’t wait to see where we can take this!

## #org-mode answers: task creation time, subtree at end, Emacs Lisp variables in TBLFM, logbook and refile

Posted: - Modified: |

In the interest of getting more tips out there so that they can be searchable, here are a few things I helped people out with on the #org-mode channel on freenode.net and through e-mail.

How can I log task creation times in Org Mode?

You can use an Org capture template.

How can I create a subtree at the end of the current entry?

C-u C-u C-RET M-right gets you the behaviour without configuration, or you can use:

(defun my/org-insert-subheading-after () (interactive) (org-insert-subheading '(16)))


and bind it to a speed command or a shortcut.

How can I refer to Emacs Lisp variables in #+TBLFM?

#+TBLFM: @1$2='(+ @1$1 my-var1);L


How can I write a command that adds a logbook entry and refiles a subtree?

Here was the source that someone asked me for help on:

#+TODO: TODO(t!) | DONE(d!)
#+NAME: startup
#+BEGIN_SRC emacs-lisp
(setq org-log-into-drawer t)
(setq org-use-speed-commands t)
(defun my/refiletree (file headline &optional arg)
(let ((pos (save-excursion
(find-file file)
(org-refile arg nil (list headline file nil pos)))
(switch-to-buffer (current-buffer)))

(org-todo "TODO")
(my/refiletree buffer-file-name "Next"))))
(org-todo "DONE")
(my/refiletree buffer-file-name "Done"))))
#+END_SRC

* Inbox
* Next
* Done


The problem was that the logbook entry was getting added to the wrong heading, since the subtree had already been refiled. It’s because logging is done in post-command-hook (example code from org-add-log-setup: (add-hook 'post-command-hook 'org-add-log-note 'append)). That’s why it gets confused. Try this. It defines a function to add to org-after-refile-insert-hook.

(setq org-log-into-drawer t)
(setq org-use-speed-commands t)
(progn
(defun ,(intern (concat "my/change-state-to-" state)) ()
(org-todo ,state)
(remove-hook 'org-after-refile-insert-hook (quote ,(intern (concat "my/change-state-to-" state)))))
'(,key
(lambda ()
(add-hook 'org-after-refile-insert-hook (quote ,(intern (concat "my/change-state-to-" state))))
(my/def-state-and-refile-shortcut "t" "TODO" "Next")
(my/def-state-and-refile-shortcut "d" "DONE" "Done")
(defun my/refiletree (file headline &optional arg)
(let ((pos (with-current-buffer (or (find-buffer-visiting file)
(find-file-noselect file))
(save-excursion
`