Category Archives: emacs

2015-11-02 Emacs News

Previous roundup – Links from,, and Youtube

2015-10-26 Emacs News

Links were from,, and Youtube. Here’s last week’s round-up, too. Enjoy!

2015-10-18 Emacs link round-up

How do you find out about cool new packages? Reddit suggests /r/emacs,, Paradox or package-list-packages, @melpa_emacs, Emacs-related blogs, gnu.emacs.sources, rubikitch’s feed, the MELPA repository (also available as a feed), Emacsist, Awesome Emacs, and other sources. ericjmritz has also been posting overviews of recently released/updated Emacs packages together with suggested config and other resources. September features: eno or avy for navigation, modalka for modal editing, nameless for namespaces, and highlight-thing for seeing other instances of a keyword under point.)

Quite a few people posted navigation tweaks. Check out these Hydra-related blog posts about Paradox, navigation, and other packages. If you use isearch a lot, swiper might be a faster way to search (it now supports visual-line-mode too), and you might like this multiple-cursors extension for it too. Multiple-cursors is neat.

There were a couple of writing-related resources, too. Emacs for Writers was a talk by Jay Dixit at the New York Emacs Meetup. Also, /u/yamadpc asked about a focused mode for writing. Suggestions included focus, darkroom-mode, writeroom-mode, and olivetti. In terms of building your own from the ground up, Emacs, naked describes variables you can set and functions you can call in order to make your Emacs screen cleaner.



Also, just for fun: Pacman.

Links from,, Youtube.

Wow, literate devops with Emacs and Org does actually work on Windows

Since I persist in using Microsoft Windows as my base system, I’m used to not being able to do the kind of nifty tricks that other people do with Emacs and shell stuff.

So I was delighted to find that the literate devops that Howard Abrams described – running shell scripts embedded in an Org Mode file on a remote server – actually worked with Plink.

Here’s my context: The Toronto Public Library publishes a list of new books on the 15th of every month. I’ve written a small Perl script that parses the list for a specified category and displays the Dewey decimal code, title, and item ID. I also have another script (Ruby on Rails, part of that lets me request multiple items by pasting in text containing the item IDs. Tying these two together, I can take the output of the library new releases script, delete the lines I’m not interested in, and feed those lines to my library request script.

Instead of starting Putty, sshing to my server, and typing in the command line myself, I can now use C-c C-c on an Org Mode block like this:

#+begin_src sh :dir /[email protected]:~
perl Business

That’s in a task that’s scheduled to repeat monthly, for even more convenience, and I also have a link there to my web-based interface for bulk-requesting files. But really, now that I’ve got it in Emacs, I should add a #+NAME: above the #+RESULTS: and have Org Mode take care of requesting those books itself.

On a related note, I’d given up on being able to easily use TRAMP from Emacs on Windows before, because Cygwin SSH was complaining about a non-interactive terminal.

ssh -l sacha  -o ControlPath=c:/Users/Sacha/AppData/Local/Temp/tramp.13728lpv.%r@%h:%p -o ControlMaster=auto -o ControlPersist=no -e none && exit || exit
Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/sbin/ssh-askpass): No such file or directory
Permission denied, please try again.
ssh_askpass: exec(/usr/sbin/ssh-askpass): No such file or directory
Permission denied, please try again.
ssh_askpass: exec(/usr/sbin/ssh-askpass): No such file or directory
Permission denied (publickey,password).

As it turns out, setting the following made it work for me.

(setq tramp-default-method "plink")

Now I can do things like the following:

(find-file "/[email protected]:~/")

… which is, incidentally, this file (edited to remove my credentials):

# Displays new books from the Toronto Public Library
# Author: Sacha Chua ([email protected])
# Usage:
# perl <category> - print books
# perl <file> <username> <password> - request books
use Date::Parse;

#!/usr/bin/perl -w
use strict;
use URI::URL;
use WWW::Mechanize;
use WWW::Mechanize::FormFiller;
use WWW::Mechanize::TreeBuilder;
use HTML::TableExtract;
use Data::Dumper;
sub process_account($$$);
sub trim($);
sub to_renew($$);
sub clean_string($);

# Get the arguments
if ($#ARGV < 0) {
    print "Usage:\n";
    print "perl <category/filename> [username] [password]\n";

my $agent = WWW::Mechanize->new( autocheck => 1 );
my $formfiller = WWW::Mechanize::FormFiller->new();
if ($#ARGV > 0) {
  my $filename = shift(@ARGV);
  my $username = "NOT ACTUALLY MY USERNAME";
  my $password = "NOT ACTUALLY MY PASSWORD";
  print "Requesting books\n";
  request_books($agent, $username, $password, $filename);
} else {
  my $category = shift(@ARGV);
  print_new_books($agent, $category);

## FUNCTIONS ###############################################

# Perl trim function to remove whitespace from the start and end of the string
sub trim($)
  my $string = shift;
  $string =~ s/^\s+//;
  $string =~ s/\s+$//;
  return $string;

sub request_books($$$$)
  my $agent = shift;
  my $username = shift;
  my $password = shift;
  my $filename = shift;

  # Read titles and IDs
  open(DATA, $filename) or die("Couldn't open file.");
  my @lines = <DATA>;

  my %requests = ();

  my $line;
  my $title;
  my $id;
  foreach $line (@lines) {
    ($title, $id) = split /\t/, $line;
    chomp $id;
    $requests{$id} = $title;

  # Log in
  log_in_to_library($agent, $username, $password);
  print "Retrieving checked-out and requested books...";
  # Retrieve my list of checked-out and requested books
  my $current_ids = get_current_ids($agent);

  # Retrieve a stem URL that I can use for requests
  my $base_url = '';
  my @already_out;
  my @success;
  my @failure;
  # For each line in the file
  while (($id, $title) = each(%requests)) {
    # Do I already have it checked out or on hold? Skip.
    if ($current_ids->{$id}) {
      push @already_out, $title . " (" . $current_ids->{$id} . ")";
    } else {
      # Request the hold
      my $url = $base_url . $id;
      if ($agent->content =~ /The hold was successfully placed/) {
        # print "Borrowed ", $title, "\n";
        ## Did it successfully get checked out? Save title in success list
        push @success, $title;
      } else {
        # Else, save title and ID in fail list
        push @failure, $title . "\t" . $id;
  # Print out success list
  if ($#success > 0) {
    print "BOOKS REQUESTED:\n";
    foreach my $title (@success) {
      print $title, "\n";
    print "\n";
  # Print out already-out list
  if ($#already_out > 0) {
    foreach my $s (@already_out) {
      print $s, "\n";
    print "\n";
  # Print out fail list
  if ($#failure > 0) {
    print "COULD NOT REQUEST:\n";
    foreach my $s (@failure) {
      print $s, "\n";
    print "\n";

sub get_current_ids($)
  my $agent = shift;
  my %current_ids = ();
  my $string = $agent->content;
  while ($string =~ m/TITLE\^([0-9]+)\^/g) {
    $current_ids{$1} = 'requested';
  while ($string =~ m/RENEW\^([0-9]+)\^/g) {
    $current_ids{$1} = 'checked out';
  return \%current_ids;

sub print_new_books($$)
  my $agent = shift;
  my $category = shift;
  $agent->follow_link(text_regex => qr/Our Newest Titles/);
  $agent->follow_link(text_regex => qr/$category/i);

  my $continue = 1;
  while ($continue) {
    if ($agent->form_with_fields('SCROLL^F')) {
    } else {
      $continue = 0;

# Print out all the entries on this page
sub print_titles_on_page($)
  my $agent = shift;
  my @titles = $agent->look_down(sub {
                                $_[0]->tag() eq 'strong' and
                                $_[0]->parent->attr('class') and
                                $_[0]->parent->attr('class') eq 'itemlisting'; });
  foreach my $title (@titles) {
    my $hold = $title->parent->parent->parent->parent->look_down(sub {
                                                          $_[0]->attr('alt') and
                                                          $_[0]->attr('alt') eq 'Place Hold'; });
    my $id = "";
    my $call_no = "";
    if ($hold && $hold->parent && $hold->parent->attr('href') =~ /item_id=([^&]+)&.*?callnum=([^ "&]+)/) {
      $id = $1;
      $call_no = $2;
    print $call_no . "\t" . $title->as_text . "\t" . $id . "\n";

sub clean_string($)
    my $string = shift;
    $string =~ s#^.*?(<form id="renewitems" [^>]+>)#<html><body>\1#s;
    $string =~ s#</form>.*#</form></html>#s;
    $string =~ s#<table border="0" bordercolor="red".*(<table border="0" bordercolor="blue" cellspacing="0" cellpadding="0">)#\1#s;
    $string =~ s#</table>.*</form>#</table></form>#s;
# Clean up for parsing
    $string =~ s#<!-- Print the date due -->##g;
    $string =~ s#<br> <!-- Displays Date -->##g;
    return $string;

sub log_in_to_library($$$) {
    my $agent = shift;
    my $username = shift;
    my $password = shift;
    $agent->current_form->value('userId', $username);
    $agent->current_form->value('password', $password);

Ah, Emacs!

2015-10-14 Emacs Hangout

Another Emacs Hangout, hooray! Thanks to everyone who participated. Enjoy watching, and I hope to see you at the next one!

Event pageMailing list for notifications

Partial list of fuzzy timestamps:

  • 0:04 using org babel for a git dashboard link
  • 0:14 org tables and timestamps – whoops, focused on the wrong video, but here’s the blog post: link
  • 0:22 projectile and tags
  • 0:32 jabber and org contacts
  • 0:37 org-download
  • 0:41 Kindle highlights
  • 0:42 archiving
  • 0:45 visible-mode
  • 0:48 company-mode
  • 0:50 elfeed, pinboard
  • 0:58 building from source

Text chat:

Eric Hanchrow 8:56 PM I’m so much more comfortable with text than video … if other people join, will I see their icons?
me 8:56 PM Yup. Text chat is totally cool, it gets saved and posted too. and I can read things into the audio for people just listening to the stream (Livestream viewers won’t see the text chat during the hangout – only people in the actual Hangout will see it, so that’s why I repeat cool stuff. )
Eric Hanchrow 8:57 PM uh … so “livestream” is something different from Hangout? :-\ livestream must be “read only”
me 8:58 PM Yup, livestream (Youtube, etc.) is read only
Eric Hanchrow 8:58 PM ah dinnertime already!
Puneeth Chaganti 9:09 PM Hi everyone.
me 9:10 PM Hi Puneeth!
Kiran Gangadharan 9:37 PM
Puneeth Chaganti 9:41 PM I have to head off folks! I’ll catch up with video later. Have a good day/night!
me 9:57 PM See you!
Dave Marquardt 10:13 PM Sacha, what was the name of that mode that scatters tasks? I think I saw something like that in orgbox…. Now I see it in the Org info. Thanks! Thanks for setting it up!

Update on Emacs Conf 2015 videos; Org Mode tables and time calculations

I spent the day cutting up the rest of the videos from the Emacs Conference 2015 stream into individual talks. I’d already cut the set of talks before lunch, but there were quite a few more after. As it turned out, keeping the video data in .ts format instead of converting it to .mp4 is actually better for Youtube processing.

Since Camtasia Studio and Movie Maker were both having problems with the large videos, I used VLC to play the video and find the timestamps at which I needed to cut the segments. I made an Org Mode table with the start and end times, and then I used the ;T flag in a table function to get the duration. A little bit of Emacs Lisp code later, and I had my ffmpeg commands. Here’s the source from my Org file:

#+NAME: emacsconf-c.ts
| Notes                                            |      Start |        End | Duration |
| Emacs configuration                              | 4:02:25.37 | 4:27:09.30 | 00:24:44 |
| Hearing from Emacs Beginners                     |    4:27:27 |    5:01:00 | 00:33:33 |
| Lightning talk: Emacs Club                       | 5:03:19.30 | 5:19:37.83 | 00:16:18 |
| Starting an Emacs Meetup - Harry Schwartz part 1 | 5:31:52.03 |    6:01:20 | 00:29:28 |
#+TBLFM: $4=$3-$2;T

#+NAME: emacsconf-a.ts
| Notes                                                    |   Start |     End | Duration |
| Starting an Emacs Meetup - Harry Schwartz part 2         |  0:0:00 | 0:20:04 | 00:20:04 |
| Literate Devops - Howard Abrams                          | 1:28:20 | 2:08:15 | 00:39:55 |
| Lightning talk: Wanderlust and other mail clients        | 2:15:04 | 2:26:55 | 00:11:51 |
| Making Emacs a Better Tool for Scholars - Erik Hetzner   | 2:27:00 | 2:57:38 | 00:30:38 |
| Wrapping up and going forward                            | 2:58:09 | 2:59:44 | 00:01:35 |
| Lightning talk: Collaborative coding with tmux and tmate | 3:00:20 | 3:05:53 | 00:05:33 |
| Lightning talk: Cask and Pellet                          | 3:05:56 | 3:09:04 | 00:03:08 |
| Lightning talk: File sharing with Git and save hooks     | 3:09:34 | 3:17:50 | 00:08:16 |
| Lightning talk: Calc                                     | 3:18:42 | 3:33:20 | 00:14:38 |
| Lightning talk: Magit                                    | 3:35:15 | 3:49:42 | 00:14:27 |
| Lightning talk: gist.el                                  | 3:53:50 | 4:01:58 | 00:08:08 |
| Lightning talk: Go                                       | 4:02:45 | 4:16:37 | 00:13:52 |
| Question: Emacs Lisp backtraces                          | 4:16:50 | 4:20:09 | 00:03:19 |
#+TBLFM: $4=$3-$2;T

#+begin_src emacs-lisp :var data=emacsconf-a.ts :var data2=emacsconf-c.ts :colnames t :results output
(let ((format-str "ffmpeg -i %s -ss %s -t %s -c:v copy -c:a copy \"EmacsConf 2015 - %s.ts\"\n"))
  (mapc (lambda (file)
    (mapc (lambda (row) 
      (princ (format format-str (car file) (elt row 1) (elt row 3) (my/convert-sketch-title-to-filename (elt row 0))))) 
     (cdr file)))
    `(("emacsconf-c.ts" . ,data2)
      ("emacsconf-a.ts" . ,data))))

and the output:

ffmpeg -i emacsconf-c.ts -ss 4:02:25.37 -t 00:24:44 -c:v copy -c:a copy "EmacsConf 2015 - Emacs configuration.ts"
ffmpeg -i emacsconf-c.ts -ss 4:27:27 -t 00:33:33 -c:v copy -c:a copy "EmacsConf 2015 - Hearing from Emacs Beginners.ts"
ffmpeg -i emacsconf-c.ts -ss 5:03:19.30 -t 00:16:18 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - Emacs Club.ts"
ffmpeg -i emacsconf-c.ts -ss 5:31:52.03 -t 00:29:28 -c:v copy -c:a copy "EmacsConf 2015 - Starting an Emacs Meetup - Harry Schwartz part 1.ts"
ffmpeg -i emacsconf-a.ts -ss 0:0:00 -t 00:20:04 -c:v copy -c:a copy "EmacsConf 2015 - Starting an Emacs Meetup - Harry Schwartz part 2.ts"
ffmpeg -i emacsconf-a.ts -ss 1:28:20 -t 00:39:55 -c:v copy -c:a copy "EmacsConf 2015 - Literate Devops - Howard Abrams.ts"
ffmpeg -i emacsconf-a.ts -ss 2:15:04 -t 00:11:51 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - Wanderlust and other mail clients.ts"
ffmpeg -i emacsconf-a.ts -ss 2:27:00 -t 00:30:38 -c:v copy -c:a copy "EmacsConf 2015 - Making Emacs a Better Tool for Scholars - Erik Hetzner.ts"
ffmpeg -i emacsconf-a.ts -ss 2:58:09 -t 00:01:35 -c:v copy -c:a copy "EmacsConf 2015 - Wrapping up and going forward.ts"
ffmpeg -i emacsconf-a.ts -ss 3:00:20 -t 00:05:33 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - Collaborative coding with tmux and tmate.ts"
ffmpeg -i emacsconf-a.ts -ss 3:05:56 -t 00:03:08 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - Cask and Pellet.ts"
ffmpeg -i emacsconf-a.ts -ss 3:09:34 -t 00:08:16 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - File sharing with Git and save hooks.ts"
ffmpeg -i emacsconf-a.ts -ss 3:18:42 -t 00:14:38 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - Calc.ts"
ffmpeg -i emacsconf-a.ts -ss 3:35:15 -t 00:14:27 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - Magit.ts"
ffmpeg -i emacsconf-a.ts -ss 3:53:50 -t 00:08:08 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - gist.el.ts"
ffmpeg -i emacsconf-a.ts -ss 4:02:45 -t 00:13:52 -c:v copy -c:a copy "EmacsConf 2015 - Lightning talk - Go.ts"
ffmpeg -i emacsconf-a.ts -ss 4:16:50 -t 00:03:19 -c:v copy -c:a copy "EmacsConf 2015 - Question - Emacs Lisp backtraces.ts"

You can watch the Emacs Conference 2015 playlist on YouTube. At some point, each talk will probably have individual wiki pages and IRC logs at . =) Enjoy!

Related tech notes: Emacs Conf video tech notes:,, livestreamer, ffmpeg