sachachua: 2017-03-27 Emacs news

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, Hacker News, planet.emacsen.org, Youtube, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

-1:-- 2017-03-27 Emacs news (Post Sacha Chua)--L0--C0--March 27, 2017 04:50 AM

Irreal: Emacser Defined

There’s a lot of truth in that, of course, but we’re planning on saving that 1 keypress millions of times.

-1:-- Emacser Defined (Post jcs)--L0--C0--March 26, 2017 05:45 PM

Irreal: Ediff Files from Dired

The prolific abo-abo has a nice bit of Elisp that you will find useful if you like to use dired for your file operations and find yourself diffing a lot of files. His snippet allows you to mark two file in dired, press e, and call ediff on the two marked files.

The code tries to put the newest file second so that ediff will display the changes in a logical way. That is, if you add “new stuff” to the original file, you want ediff to show the change as an addition of “new stuff” rather than as a deletion of it.

-1:-- Ediff Files from Dired (Post jcs)--L0--C0--March 25, 2017 05:33 PM

sachachua: 2017-03-20 Emacs news

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, Hacker News, planet.emacsen.org, Youtube, the changes to the Emacs NEWS file, and emacs-devel.

Past Emacs News round-ups

-1:-- 2017-03-20 Emacs news (Post Sacha Chua)--L0--C0--March 23, 2017 05:48 AM

Rubén Berenguel: The emacs 30 Day Challenge: Using 'gnus' to read mail


The gnus logo,
from gnus homepage
When the time to choose a mail reader for emacs came, as part of my emacs 30 Day Challenge, there were not really a lot of options. A long, long time ago I had tried vm (view mail) with no luck. I don't remember the details (it was something like 3 years ago), but the results where unappealing. The only contenders where gnus and wanderlust.

I managed to configure gnus pretty quickly: in only 30 minutes I had my gmail inbox working and was able to send mails through my main account. As an addition to gnus, I use bbdb to manage my contacts. You can read my post about bbdb and gnus integration.

I decided to give wanderlust a try, after reading a good review and configuration steps from emacs-fu. But had no luck (at least in my netbook), some kind of connectivity problem, probably due to some package which was not the correct version: wanderlust is very picky with what version of what package you have installed. I gave up and stood with gnus.

Installing and configuring gnus with gmail and multiple smtp accounts

If you have a recent emacs version, you'll have already gnus installed and you can start it with M-x gnus. But it is far better to configure it first. And it is far better to start by installing gnutls or starttls, depending on your system. You can do this with your package manager in Linux, or using fink or macports in Mac OS. This allows you to use SSL to connect to your mail servers. This is also a required step to use twittering.el (to be covered in a few days) and I guess it is also required (or should be required!) by jabber.el

I use gmail, together with several accounts from mostlymaths.net, and have configured my main account in gmail to be able to send mails through all my other accounts. Let's configure this. The following configuration is taken from the emacswiki with a few other tweaks from here and there. First C-x C-f ~/.gnus.el, and add the following lines, filling in your details
;; You need this to be able to list all labels in gmail
(setq gnus-ignored-newsgroups "")

;; And this to configure gmail imap
(setq gnus-select-method '(nnimap "gmail"
(nnimap-address "imap.gmail.com")
(nnimap-server-port 993)
(nnimap-stream ssl)))

;; My version of gnus in my Mac does not handle html messages;; correctly (the one in the netbook does, I guess it is a different;; version). The following will chose plaintext every time this is;; possible.
(setq mm-discouraged-alternatives '("text/html" "text/richtext"))

;; Available SMTP accounts. The format is;; type of connection - account in the from field - smtp server -;; port - login name - password. You can leave the password field
;; as NIL and emacs will ask every time

(defvar smtp-accounts
'(
(ssl "mainaccount@gmail.com" "smtp.gmail.com"
587 "mainaccount@gmail.com" "yourpassword")
(ssl "mainaccount@mygoogleapps" "smtp.gmail.com"
587 "mainaccount@mygoogleapps" "otherpassword")
(ssl "workaccount@university" "smtp.gmail.com"
587 "mainaccount@gmail.com" "yourpassword") ))

;; Now lets configure smtpmail.el with your name and functions to send;; mail using your smtp accounts by changing the from field
(require 'smtpmail)
(setq send-mail-function 'smtpmail-send-it
message-send-mail-function 'smtpmail-send-it
mail-from-style nil user-full-name "Your name"
smtpmail-debug-info t smtpmail-debug-verb t)

(defun set-smtp (mech server port user password)
"Set related SMTP variables for supplied parameters."
(setq smtpmail-smtp-server server smtpmail-smtp-service port
smtpmail-auth-credentials (list (list server port user
password)) smtpmail-auth-supported (list mech)
smtpmail-starttls-credentials nil)
(message "Setting SMTP server to `%s:%s' for user `%s'."
server port user))

(defun set-smtp-ssl (server port user password &optional key
cert)
"Set related SMTP and SSL variables for supplied parameters."
(setq starttls-use-gnutls t
starttls-gnutls-program "gnutls-cli"
starttls-extra-arguments nil smtpmail-smtp-server server
smtpmail-smtp-service port
smtpmail-auth-credentials (list (list server port user
password)) smtpmail-starttls-credentials (list (list
server port key cert)))
(message
"Setting SMTP server to `%s:%s' for user `%s'. (SSL
enabled.)"
server port user))

(defun change-smtp ()
"Change the SMTP server according to the current from line."
(save-excursion
(loop with from = (save-restriction
(message-narrow-to-headers)
(message-fetch-field "from"))
for (auth-mech address . auth-spec) in smtp-accounts
when (string-match address from) do (cond
((memq auth-mech '(cram-md5 plain login))
(return (apply 'set-smtp (cons auth-mech auth-spec))))
((eql auth-mech 'ssl)
(return (apply 'set-smtp-ssl auth-spec)))
(t (error "Unrecognized SMTP auth. mechanism:
`
%s'." auth-mech))) finally (error "Cannot infer SMTP
information."
))))

;; The previous function will complain if you fill the from field with;; an account not present in smtp-accounts.
(defvar %smtpmail-via-smtp (symbol-function 'smtpmail-via-smtp))

(defun smtpmail-via-smtp (recipient smtpmail-text-buffer)
(with-current-buffer smtpmail-text-buffer
(change-smtp))
(funcall (symbol-value '%smtpmail-via-smtp) recipient
smtpmail-text-buffer))

;; This wraps send mail via smtp mail, to be able to send multiple;; messages with smtpmail.
Now, we can configure the authentication process. Open ~/.authinfo and fill it with the following data

machine imap.gmail.com login john_doe@gmail.com password notapassword port 993

If you don't like to store your passwords in plain text, you can either leave it blank (gnus will ask every time for your password) or use an encrypted authinfo file. I could not use this solution, as the emacs I have in my Mac has no encryption. But you can check it if you do!

Ready to use gnus! M-x gnus. After a few seconds of data processing, you should have a buffer named *Groups*. In gnus, you subscribe to groups, and the available groups should be your gmail labels. To subscribe to something, issue U followed by a double tab. This will show all the available labels. INBOX is the one you should not miss, of course.


gnus groups -> INBOX -> new mail

Once you have INBOX in your *Groups* buffer, you may need to update it for new mails. Pressing g will fetch new mails (or news) from the server. Pressing enter will open that group and show you your unread mails. If they don't appear in the INBOX buffer, it is somehow usual. If you had already checked and read your mail, fetch again in the *Groups* buffer and press enter, it takes you to the old INBOX buffer, without the new mails. Press M-g in it to fetch new headers and summaries. Pressing enter in your mails of course opens them.

Deleting mails, composing and replying

Now let's say you want to move a message to the Trash folder in your Gmail account, or your Spam folder. Scroll to your mail and press B m (Backend command + move). Now you can choose which folder, and if everything worked smoothly, you could press double tab and show all folders. If not, write [Gmail]/Trash. This is the correct gmail trash folder. Once you are done with operating with your mails in this way, press M-g to really do move them to the trash (and by the way, marking them in Gmail as read).

To quit gnus, in the groups buffer press q (or Q if you don't want to save "your progress"). In case of being lost... Please, use the menus: gnus has a menu for almost anything and they are quite descriptive. And more important, never leave gnus without properly q or Quitting. Also, in my netbook I can't suspend to RAM and then be able to re-start gnus. I have to q first. But in my Mac it works correctly.

We are almost done covering the simplest way to use gnus. Of course, we want to be able to write emails, or reply to mails we got! In the INBOX buffer, that would be r while reading or selecting a mail. To compose an email out in the cold, you can either use m in INBOX or *Groups* buffers. If you are in any buffer, you can compose an email with C-x m.

And if you use bbdb (the big brother database, a contact manager with automatic fetching of gnus data), which I will cover in the next writing, you can compose an email after searching for someone (M-x bbdb query and then m in the resulting search results buffer). You can read about basic use of bbdb in A glimpse of bbdb and gnus.

Searching your mail through imap

And another interesting thing would be to be able to search within your mail. To do so you will need the nnir package and add a line in the imap configuration.
;; To be able to search within your gmail/imap mail
(require 'nnir)

(setq gnus-select-method '(nnimap "gmail"
(nnimap-address "imap.gmail.com")
(nnimap-server-port 993)
(nnimap-stream ssl))
(nnir-search-engine imap))
You should subscribe to [Gmail]/All mail, and then press G G to search within your mail. This is a little slow... But works.

I'm still fiddling with gnus, and learning to use it more effectively, but this can get you going with using it for reading your mail. If I learn something new along the way (or someone more used to gnus posts it here) I'll add it here or in a new gnus post.

If you enjoyed this, please share it with your emacs friends through Reddit, Hackernews or whatever you enjoy.

-1:-- The emacs 30 Day Challenge: Using 'gnus' to read mail (Post Rubén Berenguel (noreply@blogger.com))--L0--C0--March 21, 2017 05:43 PM

Pragmatic Emacs: Speedy sorting in dired with dired-quick-sort

The package dired-quick-sort gives you a pop-up menu with lots of useful options to sort your dired view by name, time, size and extension, and optionally group all of the directories together at the top of the listing. This can be a bit fiddly and dired-quick-sort makes it really easy.

Install the package with

(use-package dired-quick-sort
  :ensure t
  :config
  (dired-quick-sort-setup))

and then hit S in a dired buffer to bring up the sorting menu. Your sorting choice is then remembered for new dired buffers.

-1:-- Speedy sorting in dired with dired-quick-sort (Post Ben Maughan)--L0--C0--March 20, 2017 08:02 PM

Raimon Grau: Browsing allegro lisp docs inside emacs

While programming, I love to read documentation using helm-dash. I've created quite a few docsets for apps/languages that lacked them in the official repos.

Currently I was using python, common lisp, Picolisp, and Redis, but I felt I was going too often to the franz's Allegro Lisp documentation site.  It's nice and loads fast, but it doesn't provide any useful search.

So I created a dash docset for Franz's Allegro Lisp.  As usual, it's in my github.

And here's a little gif I recorded to see how does it look.


-1:-- Browsing allegro lisp docs inside emacs (Post Raimon Grau (noreply@blogger.com))--L0--C0--March 20, 2017 05:05 PM

Marcin Borkowski: Deleting all instances of a LaTeX environment

Today, someone asked on the AUCTeX-devel mailing list about a way to delete (or comment out) all the instances of certain environment. Here’s my solution.
-1:-- Deleting all instances of a LaTeX environment (Post)--L0--C0--March 18, 2017 08:56 PM

(or emacs: Quickly ediff files from dired

ediff.el --- a comprehensive visual interface to diff & patch

I wrote about ediff years ago. Today, I'll just reference a useful ediff snippet from my config that I've added some time ago and refined only recently.

The premise is quite simple: press e in dired-mode to immediately ediff two marked files, no questions asked:

(define-key dired-mode-map "e" 'ora-ediff-files)

And here's the code, with a few bells and whistles:

;; -*- lexical-binding: t -*-
(defun ora-ediff-files ()
  (interactive)
  (let ((files (dired-get-marked-files))
        (wnd (current-window-configuration)))
    (if (<= (length files) 2)
        (let ((file1 (car files))
              (file2 (if (cdr files)
                         (cadr files)
                       (read-file-name
                        "file: "
                        (dired-dwim-target-directory)))))
          (if (file-newer-than-file-p file1 file2)
              (ediff-files file2 file1)
            (ediff-files file1 file2))
          (add-hook 'ediff-after-quit-hook-internal
                    (lambda ()
                      (setq ediff-after-quit-hook-internal nil)
                      (set-window-configuration wnd))))
      (error "no more than 2 files should be marked"))))

Some notes on how the extra code adds convenience:

  1. In case no files are marked, the file at point is used as the first file, and read-file-name is used for the second file. Since I have the magic (setq dired-dwim-target t) in my config, in case a second dired buffer is open, dired-dwim-target-directory will offer it as the starting directory during completion. Very useful to compare two files in two different directories.

  2. Depending on the order of the arguments to ediff-files, the changes will appear either as added or removed; file-newer-than-file-p tries to put the arguments in a logical order by looking at the files' last change times.

  3. ediff-after-quit-hook-internal is used to restore the previous window configuration after I quit ediff with q.

That's about it. Hopefully, it's useful. Happy hacking.

-1:-- Quickly ediff files from dired (Post)--L0--C0--March 17, 2017 11:00 PM

Pragmatic Emacs: Export org-mode headlines to separate files

I was recently managing a set of interviews and I had my notes on all of the candidates in a single org file, with each candidate under their own top-level headline:

* J Kepler
 - Nice work on orbits

* I Newton
 - Versatile
 - Hard to work with

* C Sagan
 - Good communication skills

However, I wanted to generate a separate pdf file for each candidate that I could circulate to interviewers (since each interviewer was only interviewing a subset of applicants).

I came across this stackexchange answer that demonstrated how to build a function to export top level headlines to separate files. There are a few variations on that page, and I put together the slightly tweaked version below. All of the credit goes to stackexchange user itsjeyd for a very detailed answer. In my version I hard code it to export to pdf, save the file first, and apply the export options from the parent file to each of the new files that are created. The new files have a name taken from the headline, with spaces replaced by underscores, unless the :EXPORT_FILE_NAME: property is set for a headline.

;; export headlines to separate files
;; http://emacs.stackexchange.com/questions/2259/how-to-export-top-level-headings-of-org-mode-buffer-to-separate-files
(defun org-export-headlines-to-pdf ()
  "Export all subtrees that are *not* tagged with :noexport: to
separate files.

Subtrees that do not have the :EXPORT_FILE_NAME: property set
are exported to a filename derived from the headline text."
  (interactive)
  (save-buffer)
  (let ((modifiedp (buffer-modified-p)))
    (save-excursion
      (goto-char (point-min))
      (goto-char (re-search-forward "^*"))
      (set-mark (line-beginning-position))
      (goto-char (point-max))
      (org-map-entries
       (lambda ()
         (let ((export-file (org-entry-get (point) "EXPORT_FILE_NAME")))
           (unless export-file
             (org-set-property
              "EXPORT_FILE_NAME"
              (replace-regexp-in-string " " "_" (nth 4 (org-heading-components)))))
           (deactivate-mark)
           (org-latex-export-to-pdf nil t)
           (unless export-file (org-delete-property "EXPORT_FILE_NAME"))
           (set-buffer-modified-p modifiedp)))
       "-noexport" 'region-start-level))))
-1:-- Export org-mode headlines to separate files (Post Ben Maughan)--L0--C0--March 13, 2017 09:09 PM

Marcin Borkowski: Ibuffer

Some day, when you have half an hour to spare, press M-x ibuffer RET and then h. Then take your jaw from the floor and put it back in place again.
-1:-- Ibuffer (Post)--L0--C0--March 13, 2017 08:42 PM

Bryan Murdock: Quick Thoughts on Creating Coding Standards

Introduction

No team says, "write your code however the heck you want." Unless you are coding alone, it generally helps to have an agreed upon coding standard. Agreeing upon a coding standard, however, can be a painful process full of heated arguments and hurt feelings. This morning I thought it might be useful to first categorize coding standard items before starting the arguments. My hope is that once we categorize coding standard items we can use better decision criteria for each category of items and cut down on arguing. Below are the categories I came up with really quickly with descriptions, examples, and decision criteria for each category. Feedback is welcome in the comments.

Categories of Things in Coding Standards

Language Specific Pitfalls

Characteristics​

  • not subjective, easy to recognize pattern
  • well recognized in the industry as dangerous
  • people have war stories and about these with associated scares to prove it

Examples

  • no multiple declarations on one line in C
  • Cliff Cummings rules for blocking vs. non-blocking assignments in Verilog
  • no willy nilly gotos in C
  • no omitting braces for one liner blocks (or begin-end in Verilog)
  • no compiler warnings allowed

How to resolve disputes on which these should be in The Coding Standard?

Defer to engineers with best war stories. If nobody has a war story for one, you can probably omit it (or can you?).

General Readability/Maintainability

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." –Martin Fowler

Characteristics

  • things that help humans quickly read, understand, and safely modify code
  • usually not language specific
  • the path from these items to bugs is probably not as clear as with the above items, but a path does exist

Examples

  • no magic numbers
  • no single letter variable names
  • keep functions short
  • indicators in names (_t for typedef's, p for pointers, etc.)

How to resolve disputes on which of these should be in The Coding Standard?

If someone says, "this really helps me" then the team should suck it up and do it. This is essentially the "put the slowest hiker at the front of the group" principle.


Alternatively these can be discussed on a case by case basis during code reviews instead of being codified in The Coding Standard. Be prepared for more "lively" code reviews if you go this route.

Code Formatting

The biggest wars often erupt over these because they are so subjective. This doesn't have to be the case.

Characteristics

  • these probably aren't really preventing any bugs
  • most can easily be automatically corrected
  • are largely a matter of taste
  • only important for consistency (which is important!)

Examples

  • amount of indent
  • brace style
  • camelCase vs. underscore_names
  • 80 column rule
  • dare I even mention it? tabs vs. spaces

How to resolve disputes on which of these should be in The Coding Standard?

Don't spend a long time arguing about these. Because they are so subjective and not likely to cause or reduce bugs one way or the other, nobody should get bent out of shape if their preference is not chosen by the team. Give everyone two minutes to make their case for their favorite, have a vote, majority wins, end of discussion. Use an existing tool (astyle, autopep8, an emacs mode, whatever is available for the language) to help people follow these rules.
-1:-- Quick Thoughts on Creating Coding Standards (Post Bryan (noreply@blogger.com))--L0--C0--March 13, 2017 07:35 PM

John Stevenson: Spacemacs - Managing Broken Emacs Packages

There is a great deal of development in Spacemacs and the wider Emacs community, especially around the new features of Emacs 26. So sometimes bugs appear in Emacs packages, but usually for not very long. Here is a simple guide to avoiding broken packages in your Spacemacs environment on the rare occasion that this happens.

One way to track bugs is to watch the Spacemacs Github repository. You can also join the Spacemacs discussions on Gitter.im

Rolling back a package update

I update Emacs packages at least 1 a month using the Update Packages link on the Spacemacs homepage. If one of the new versions of a packages contains a bug, then I perform a rollback using the Rollback Package Updates link.

Spacemacs - Home - Update Packages

Pinning a version for a known buggy package

If you know there is a bug with a specific package before you update all the packages, then you can add the name of that package to dotspacemacs-frozen-packages list.

You need to restart Spacemacs for the change to take effect, but afterwards you can update the rest of your packages without updating any of the frozen packages.

Rollback is not an option

If you can’t rollback, you can tell Spacemacs to install a working version of the broken package by adding it to spacemacs-additional-packages with a recipe.

For example, at the initial time of writing there was a bug in the smartparens package although this was quickly fixed.

To temporarily pin that package to a known good version, we would have added the following to spacemacs-additional-packages:

1
2
3
4
5
(smartparens
:location (recipe
:fetcher github
:repo "Fuco1/smartparens"
:commit "73b9dd0c70f381aee2da8c8b27f79019aa80dcae"))

This temporary fix is no longer need as the Smartparens package was quickly fixed by the author. Smartparens is only used as an example. Thank you.

Summary

We have discussed an easy way to manage broken Emacs packages with Spacemacs, so hopefully you can quickly fix any situation that may occur with packages.

If you do find any bugs in a package then you can also submit an issue or pull request to the relevant package so you wont need to manage frozen or additional packages for long.

My thanks and gratitude goes out to all the Spacemacs and Emacs maintainers and contributors who all make Emacs the best tool out there.

Thank you.
@jr0cket

-1:-- Spacemacs - Managing Broken Emacs Packages (Post)--L0--C0--March 13, 2017 09:05 AM

Manuel Uberti: Clojure it is

Last Friday I finally told my boss that I am going to leave his company for another job.

It’s not the first time in my working life that I want to move to greener pastures. For different reasons I changed jobs quite a lot in the last 10 years. However, this is the first time that I made my decision based on the programming language being used in the office.

As much as I had fun working with Java 8, in the last months there has been little of it. Bouncing back and forth between Java 7 and PHP 5.6 for legacy code maintenance is not exactly my idea of fun.

Both Clojure and functional programming changed the way I think about solving problems with code. I often found myself thinking outside the boundaries of OOP, craving for pure and higher-order functions, all of which are just out of reach in the afore mentioned versions of Java and PHP.

The adoption of Clojure by Italian software houses is still close to none. It’s been a while since I started looking for a job with Clojure, but until now the only opportunities I found required moving to another country. I even tried to convince myself I was willing to pack my bags again, but family comes first and deep in my heart I knew I couldn’t ask my wife to leave everything behind.

Imagine my shock when I heard that 7Bridges was hiring. Marco Dalla Stella, CTO and Co–founder of the company, is basically the man who guided me through my first steps with Clojure. It was him, 2 years ago, who pointed me to Programming Clojure and The Joy of Clojure. It was him who joined me for a trip to Bologna where LambdaCon happened. He’s also an Emacs user, which means he must be one of the good guys.

And now I can’t wait to start working with Clojure for real. I celebrated the beginning of this new adventure with a new Dell XPS 13 which will surely be perfect for what I have in mind.

Eventually, Clojure it is.

-1:-- Clojure it is (Post)--L0--C0--March 12, 2017 12:00 AM

John Stevenson: Org-Mode Driven Presentations With Org-Reveal & Spacemacs

Creating web-based presentations has never been easier now that org-revel is just an option in the org layer for Spacemacs. By adding a variable to the org layer in the Spacemacs configuration and setting the location of Reveal.js on your file space you are ready to convert .org files into lovely presentations.

You can see examples of my presentations at http://jr0cket.co.uk/slides

If you have not used org-reveal before, see my previous articles on creating cool slides with Emacs Org-mode and Org-reveal, please note that article has an older configuration. If you have not experienced the amazing Org-mode, then see how to manage your developer life with this amazing tool.

Configure the Org layer

Open the ~/.spacemacs configuration file, SPC f e d (file, emacs, dotfile).

Search for the dotspacemacs-configuration-layers using SPC / (or just scroll down as its near the top of the file)

Now add org-enable-reveal-js-support t as a variable to the org layer, so your org layer entry looks as follows

1
2
(org :variables
org-enable-reveal-js-support t)

If you already have org-mode installed, then simply reload the ~/.spacemacs configuration with SPC f e R.

If this is the first time you are installing org-mode, or org-reveal does’t seem to work, I suggest restarting Spacemacs with SPC q r.

In my ~/.spacemacs configuration file I also have github support to create README files that display on Github repositories.

1
2
3
(org :variables
org-enable-github-support t
org-enable-reveal-js-support t)

Configure the location of Reveal.js

You can specify the location of Reveal.js in each .org file you write by using the variable REVEAL_ROOT. You can use a local directory on your file space or a content delivery network (for which you need to be online to convert your files)

1
#+REVEAL_ROOT: http://cdn.jsdelivr.net/reveal.js/3.0.0/

I prefer to use a local copy of Reveal.js. This does mean I need to download and update Reveal.js manually, however it means that do not need to include the REVEAL_ROOT in each .org file. Instead you need to set the (setq org-reveal-root "") in ``

I place the css, js, plugin and stylesheet directories into a folder that contains all my .org files, so I set an empty org-reveal-root as follows

1
(setq org-reveal-root "")

I deploy my slides on Github pages which does cache some artefacts, so hopefully it also caches org-reveal. I have never experienced any issues with speed browsing the slides.

Creating your slides

Create a new file with the file extension .org, for example my-awesome-presentation.org. You can add meta-data at the top for the title slide and all other slides are defined with a single *. Child slides, appearing underneath a parent slide are created with two * characters, ie. **

I have detailed how to create your first presentation with org-mode and org-reveal in my article entitled Creating Cool Slides With Emacs Org-Mode and Revealjs.

Creating (rendering) the Reveal.js slides

You can use the Org-export dispatcher to convert your .org file into a beautiful Reveal.js presentation:

Use C-c C-e to open the dispatcher menu, select R for the reveal section and R to render the .org file as an .html file of the same name.

Or use C-c C-e R B to render the .html file and open it in a new browser window.

Spacemacs Org-reveal - Org-export Dispatcher

If you prefer using the Spacemacs menu, you can use following commands to convert your .org file:

1
2
3
SPC SPC org-reveal-export-to-html
SPC SPC org-reveal-export-to-html-and-browse

Publishing the slides on Github

Github Pages are a great place for publishing your Reveal.js presentations or any static web content. For existing repositories you simply commit your content to a gh-pages branch or you can create a specific user or organisation repository and commit to the master branch.

I wrote about sharing your Revealjs slides on Github Pages previously, so I wont repeat myself here.

Thank you.
@jr0cket

-1:-- Org-Mode Driven Presentations With Org-Reveal &amp; Spacemacs (Post)--L0--C0--March 08, 2017 09:34 AM

emacsninja: Making Emacs More Presentable

I do occasionally hold talks, mostly about Lisp-related topics. My medium of choice is PDF, as generated by Org’s export with the Beamer backend. When it’s demonstration time, Emacs isn’t nearly as simple to adjust for comfortable viewing as a browser or terminal. My first instinct was to look for a function that allows increasing the font size, similar to C-+. It turns out that C-x C-+ is a thing, however it’s not ideal as it only increases the font size of the current buffer. A quick look at the sources reveals why:

(define-minor-mode text-scale-mode
  "..."
  :lighter (" " text-scale-mode-lighter)
  (when text-scale-mode-remapping
    (face-remap-remove-relative text-scale-mode-remapping))
  (setq text-scale-mode-lighter
        (format (if (>= text-scale-mode-amount 0) "+%d" "%d")
                text-scale-mode-amount))
  (setq text-scale-mode-remapping
        (and text-scale-mode
             (face-remap-add-relative 'default
                                          :height
                                          (expt text-scale-mode-step
                                                text-scale-mode-amount))))
  (force-window-update (current-buffer)))

text-scale-mode is implemented in terms of face-remap-add-relative, a function describing itself as “Add a face remapping entry of FACE to SPECS in the current buffer.”. Funnily enough, both live in face-remap.el, probably because scaling text is merely a demonstration of the buffer-local face remapping capabilities of Emacs. While it’s a cute demo, it’s clearly not what I’d want from a C-+ replacement, so I wrote an alternative solution operating on the frame:

(defun my-alter-frame-font-size (fn)
  (let* ((current-font-name (frame-parameter nil 'font))
         (decomposed-font-name (x-decompose-font-name current-font-name))
         (font-size (string-to-int (aref decomposed-font-name 5))))
    (aset decomposed-font-name 5 (int-to-string (funcall fn font-size)))
    (set-frame-font (x-compose-font-name decomposed-font-name))))

(defun my-inc-frame-font-size ()
  (interactive)
  (my-alter-frame-font-size '1+))

(defun my-dec-frame-font-size ()
  (interactive)
  (my-alter-frame-font-size '1-))

(global-set-key (kbd "C-+") 'my-inc-frame-font-size)
(global-set-key (kbd "C-=") 'my-inc-frame-font-size)
(global-set-key (kbd "C--") 'my-dec-frame-font-size)

This is a bit less hacky, but still disgusting. The code fetches the font name (which curiously comes in the XLFD notation) from the frame, converts it into an array, extracts the font size, manipulates it, puts it back into the array, converts it to a font name and sets the frame’s font to it. You can find this snippet and many more in my init.org, so if you haven’t already, give it a look to find more goodies!

-1:-- Making Emacs More Presentable (Post Vasilij Schneidermann)--L0--C0--March 05, 2017 12:32 PM

Matthias Pfeifer: Copying files between dired buffers

There is a couple of packages for emacs that really have application character. Like for example: https://www.emacswiki.org/emacs/Magit https://www.emacswiki.org/emacs/EmacSpeak https://www.emacswiki.org/emacs/GnusTutorial https://github.com/skeeto/elfeed https://emacswiki.org/emacs/Sunrise_Commander And there are propably some more. Me personally – I did not adopt well to the „App in Emacs“ approach as I use none of the mentioned packages. It’s not a categorical decision, I … Copying files between dired buffers weiterlesen
-1:-- Copying files between dired buffers (Post Matthias)--L0--C0--March 03, 2017 01:04 PM

emacspeak: Emacs: Check Interactive Call For Emacspeak

Emacs: Check Interactive Call For Emacspeak

1 Background

Emacspeak uses advice as the means to speech-enable Emacs.
Emacspeak's advice forms need to check if the function being
speech-enabled is being called interactively — otherwise one would
get a lot of chatter as these functions get called from within elisp
programs, e.g. functions like forward-sexp or kill-sexp, that play
the dual role of both an interactive command, as well as a convenient
elisp function.



Until Emacs 24, the solution used was to write code that did the
following check:


(when (interactive-p) ...

In Emacs-24, interactive-p was made obsolete and replaced with

(called-interactively-p 'interactive)

Emacspeak initially used the above form to perform the equivalent
check. However, around the same time, Emacs' advice implementation
went through some changes, and there was an attempt to replace
advice.el with nadvice.el.


At the end of that round of changes, some problems emerged with the
new called-interactively-p implementation; specifically, calling
:called-interactively-p_ within around advice forms resulted in hard
to debug errors, including one case of infinite recursion involving
library smie.el when invoked from within ruby-mode.


After studying the problem in depth in 2014, I decided to create an
Emacspeak-specific implementation of the is-interactive check.


The resulting implementation has worked well for the last 30 months;
this article is here mostly to document how it works, and the reason
for its existence. Note that Emacspeak uses this custom predicate
only within advice forms. Further, this predicate has been coded
to only work within advice forms created by emacspeak. This
constraint can likely be relaxed, but the tighter implementation is
less risky.


2 Implementation — ems-interactive-p

2.1 Overview

Within an advice forms defined by Emacspeak, detect if the enclosing
function call is the result of explicit user interaction, i.e. by
pressing a key, or via an explicit call to
call-interactively. Emacspeak produces auditory feedback only if
this predicate returns t.


We first introduce a flag that will be used to record if the enclosing
(containing) function has an Emacspeak-defined advice on it and is
called interactively — these are the only cases that our predicate
needs to test.

(defvar ems-called-interactively-p nil
  "Flag that records if containing function was called interactively."

Next, we define a function that checks if interactive calls to a
function should be recorded. We're only interested in functions that
have an advice form defined by Emacspeak — all Emacspeak-defined
advice forms have the name emacspeak.


(defun ems-record-interactive-p (f)
  "Predicate to test if we need to record interactive calls of
this function. Memoizes result for future use by placing a
property 'emacspeak on the function symbol."
  (cond
   ((not (symbolp f)) nil)
   ((get f 'emacspeak) t) ; already memoized
   ((ad-find-some-advice f 'any  "emacspeak") ; there is an emacspeak advice
    (put f 'emacspeak t)) ; memoize for future and return true
   (t nil)))

This is a memoized function that remembers earlier invocations by
setting property emacspeak on the function symbol.


All advice forms created by Emacspeak are named emacspeak, so we
can test for the presence of such advice forms using the test:


(ad-find-some-advice f 'any  "emacspeak")

If this test returns T, we memoize the result and return it.


Next, we advice function call-interactively to check
if the function being called interactively is one of the functions
that has been adviced by Emacspeak. If so, we record the fact in the
previously declared global flag
ems-called-interactively-p.



(defadvice call-interactively (around emacspeak  pre act comp)
  "Set emacspeak  interactive flag if there is an Emacspeak advice 
on the function being called."
  (let ((ems-called-interactively-p ems-called-interactively-p)) ; preserve enclosing state
    (when (ems-record-interactive-p (ad-get-arg 0))
      (setq ems-called-interactively-p (ad-get-arg 0)))
    ad-do-it))

We define an equivalent advice form on function
funcall-interactively as well. Now, whenever any function that has
been adviced by Emacspeak is called interactively, that interactive
call gets recorded in the global flag. In the custom Emacspeak
predicate we define, we check the value of this flag, and if
set, consume it, i.e. unset the flag and return T.


(defsubst ems-interactive-p ()
  "Check our interactive flag.
Return T if set and we are called from the advice for the current
interactive command. Turn off the flag once used."
  (when ems-called-interactively-p                 ; interactive call
    (let ((caller (cl-second (backtrace-frame 1))) ; name of containing function
          (caller-advice  ;advice generated wrapper
           (ad-get-advice-info-field ems-called-interactively-p  'advicefunname))
          (result nil))
      (setq result
            (or (eq caller caller-advice) ; called from our advice
                (eq ems-called-interactively-p caller))) ; called from advice wrapper
      (when result
        (setq ems-called-interactively-p nil) ; turn off now that we used  it
        result))))

The only fragile part of the above predicate is the call to
backtrace-frame which we use to discover the name of the enclosing
function. Notice however that this is no more fragile than the current
implementation of called-interactively-p — which also uses
backtrace-frame; If there are changes in the byte-compiler, this
form may need to be updated. The implementation above has the
advantage of working correctly for Emacspeak's specific use-case.

-1:-- Emacs: Check Interactive Call For Emacspeak (Post T. V. Raman (noreply@blogger.com))--L0--C0--March 01, 2017 05:24 PM

Matthias Pfeifer: Show long filenames in ibuffer

I have customized my ibuffer-format to have the name column width set to 36. This is fine in 99% of the filenames showing up there. However I also have to access a couple of files that have a common prefix that is longer then 36 characters. This way the files cannot be distinguished in ibuffer… … Show long filenames in ibuffer weiterlesen
-1:-- Show long filenames in ibuffer (Post Matthias)--L0--C0--February 28, 2017 09:52 AM

emacshorrors: Less Than Exceptional

As of a few weeks ago, I’ve become part of Evil’s new maintainer team. Most of the bugs we get are not quite Evil’s fault, but rather that of other components it relies upon, such as Emacs. #785 is a perfect example of this observation. Take a look at the sources of the function responsible for the reported behavior and see whether you can find what’s wrong about it:

DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
       doc: ...)
  (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
{
  ptrdiff_t idx;
  Lisp_Object cmd;
  Lisp_Object c;
  ptrdiff_t length;
  bool t_ok = !NILP (accept_default);

  keymap = get_keymap (keymap, 1, 1);

  length = CHECK_VECTOR_OR_STRING (key);
  if (length == 0)
    return keymap;

  idx = 0;
  while (1)
    {
      c = Faref (key, make_number (idx++));

      if (CONSP (c) && lucid_event_type_list_p (c))
        c = Fevent_convert_list (c);

      /* Turn the 8th bit of string chars into a meta modifier.  */
      if (STRINGP (key) && XINT (c) & 0x80 && !STRING_MULTIBYTE (key))
        XSETINT (c, (XINT (c) | meta_modifier) & ~0x80);

      /* Allow string since binding for `menu-bar-select-buffer'
         includes the buffer name in the key sequence.  */
      if (!INTEGERP (c) && !SYMBOLP (c) && !CONSP (c) && !STRINGP (c))
        message_with_string ("Key sequence contains invalid event %s", c, 1);

      cmd = access_keymap (keymap, c, t_ok, 0, 1);
      if (idx == length)
        return cmd;

      keymap = get_keymap (cmd, 0, 1);
      if (!CONSP (keymap))
        return make_number (idx);

      maybe_quit ();
    }
}

If you haven’t spotted it, the function never signals an exception for the exceptional case of an invalid key sequence. Instead, it returns one of the few types that aren’t allowed in a definition, namely an integer. It’s up to the caller to handle this case on their own, something the majority of Emacs packages rightfully neglect to do as even + informs you about invalid input. This design decision reeks of the many ways of signalling errors in C and worse, cannot be properly fixed as there’s code inside Emacs relying on the integer return type. There is even a lookup-key-ignore-too-long in Emacs core that looks a lot like what I wrote, but it’s part of menu-bar.el for whatever reason and not advertised at all.

tl;dr: In-band signalling sucks big time.

-1:-- Less Than Exceptional (Post Vasilij Schneidermann)--L0--C0--February 26, 2017 05:46 PM

Got Emacs?: Emacs 25.2 RC2 out

The second release candidate of what will be Emacs 25.2 is out.
-1:-- Emacs 25.2 RC2 out (Post sivaram (noreply@blogger.com))--L0--C0--February 26, 2017 07:51 AM

Chen Bin (redguardtoo): Find the buffer with Chinese name

We can find the buffer with Chinese name efficiently by using the first character of pinyin.

Here is the code (ivy and pinyinlib is required):

(defun ivy-switch-buffer-matcher-pinyin (regexp candidates)
  (unless (featurep 'pinyinlib) (require 'pinyinlib))
  (let* ((pys (split-string regexp "[ \t]+"))
         (regexp (format ".*%s.*"
                         (mapconcat 'pinyinlib-build-regexp-string pys ".*"))))
    (ivy--switch-buffer-matcher regexp candidates)))

(defun ivy-switch-buffer-by-pinyin ()
  "Switch to another buffer."
  (interactive)
  (unless (featurep 'ivy) (require 'ivy))
  (let ((this-command 'ivy-switch-buffer))
    (ivy-read "Switch to buffer: " 'internal-complete-buffer
              :matcher #'ivy-switch-buffer-matcher-pinyin
              :preselect (buffer-name (other-buffer (current-buffer)))
              :action #'ivy--switch-buffer-action
              :keymap ivy-switch-buffer-map
              :caller 'ivy-switch-buffer)))

You can M-x ivy-switch-buffer-by-pinyin to switch buffer.

The algorithm of pinyinlib is simple. We build a big lookup table to convert the a plain English string into a regular expression containing Chinese characters.

You can apply the same algorithm to other non-English languages.

-1:-- Find the buffer with Chinese name (Post Chen Bin)--L0--C0--February 26, 2017 04:27 AM

Manuel Uberti: Dynamically change font size in Emacs

I take my Emacs configuration with me on every computer I use. I also plug a big external display —and the awesome Das Keyboard 4 Ultimate— during long coding sessions, so it is only natural that I have to tailor my setup to accommodate different font sizes.

Being the customizable editor that Emacs is, it wasn’t hard to devise a neat trick to please my needs.

First, a simple function to set the default fonts.

(defun mu-setup-main-fonts (default-height variable-pitch-height)
  "Set up default fonts.

Use DEFAULT-HEIGHT for default face and VARIABLE-PITCH-HEIGHT
for variable-pitch face."
  (set-face-attribute 'default nil
                      :family "Source Code Pro"
                      :height default-height)
  (set-face-attribute 'variable-pitch nil
                      :family "Fira Sans"
                      :height variable-pitch-height
                      :weight 'regular))

Now I just have to call this function with the proper values for :height according to the screen size.

(when window-system
  (if (> (x-display-pixel-width) 1800)
      (mu-setup-main-fonts 150 160)
    (mu-setup-main-fonts 130 140)))

Of course, more specific settings for various display resolutions are just a cond away.

-1:-- Dynamically change font size in Emacs (Post)--L0--C0--February 26, 2017 12:00 AM

(or emacs: Make it so&#58 file1 -> Makefile -> file2

Intro

make-it-so is an old package of mine that I haven't yet highlighted on the blog. This package helps you manage a collection of makefiles that are used to generate new files from existing files using shell commands.

You can think of these makefiles as a directory of shell functions, arranged by the extension of the files that they operate on:

$ cd make-it-so && find recipes -name Makefile
recipes/ipynb/to-md/Makefile
recipes/ogv/crop/Makefile
recipes/ogv/trim/Makefile
recipes/ogv/to-gif/Makefile
recipes/pdf/to-txt/Makefile
recipes/md/to-org/Makefile
recipes/md/to-html/Makefile
recipes/cue/split/Makefile
recipes/dot/to-png/Makefile
recipes/m4a/to-mp3/Makefile
recipes/flac/to-mp3/Makefile
recipes/gif/gifsicle/Makefile
recipes/svg/to-png/Makefile
recipes/chm/to-pdf/Makefile
recipes/txt/encode-utf8/Makefile
recipes/mp4/to-mp3/Makefile
recipes/mp4/trim/Makefile
recipes/mp4/replace-audio/Makefile
recipes/png/to-gif/Makefile

When you call make-it-so on a particular file, you get completion for the recipes that are available for that file extension, along with an option to create a new recipe.

Example 1: convert pdf to txt

Suppose you want to convert a PDF file test.pdf to a text file test.txt.

In case the recipe is in your collection, you don't have to remember the command or the command switches to do it anymore:

  1. Navigate to test.pdf in dired and press , (bound to make-it-so).
  2. Select the recipe you want using completion: to-txt is already provided.
  3. Your file and the makefile recipe are moved to the staging area:

    ./to-txt_test.pdf/test.pdf
    ./to-txt_test.pdf/Makefile
    
  4. The makefile is opened in a new buffer with the following bindings:

    • f5 (mis-save-and-compile) will run compile, creating test.txt in the current directory.
    • C-, (mis-finalize) will finalize the operation, moving test.pdf and test.txt to the parent directory (where test.pdf was before), and deleting the staging directory.
    • C-M-, (mis-abort) will move test.pdf back to its initial location and delete all generated files. This command is effectively an undo for make-it-so.

It takes a large chunk of text to describe everything, but the key sequence for doing all this is quite short:

  1. , - make-it-so.
  2. RET - select to-txt.
  3. f5 - create test.txt.
  4. C-, - finalize.

Example 2: make a gif from a series of png images

I'll describe the process of creating a high quality gif like this one, which describes the effect of the C key in lispy:

lispy-convolute

First, I use kazam to take two png screenshots of my Emacs screen:

$ ls -1 *.png
Screenshot 2017-02-25 16:14:49.png
Screenshot 2017-02-25 16:15:10.png

I plan to use gifsicle to sequence the still images into a gif. But it only takes gif as the input format, so first I have to convert my png files to non-animated gif files.

I open the dired buffer where they are located and mark them with m (dired-mark). Then call make-it-so with , and select to-gif recipe. This recipe has no parameters, so there's nothing else to do but f5 C-,. Two new files are created:

$ ls -1 *.png *.gif
Screenshot_2017-02-25 16:14:49.gif
Screenshot_2017-02-25 16:14:49.png
Screenshot_2017-02-25 16:15:10.gif
Screenshot_2017-02-25 16:15:10.png

Note that the file names (the defaults of kazam) are problematic when used with makefiles, since they contain spaces and colons. The Elisp layer of make-it-so takes care of that. It renames the files back and forth so that the logic in the makefiles remains simple.

Next, I mark the two gif files using *% (dired-mark-files-regexp), press , once more and select the gifsicle recipe. I'm presented a makefile with the following contents:

# ——— parameters —————————————————————————————————

# delay between frames in hundredths of a second
delay = 60

# ——— implementation —————————————————————————————
DIRGIF = $(shell ls *.gif | grep -v anime.gif)

all: anime.gif

anime.gif: Makefile $(DIRGIF)
    rm -f anime.gif
    gifsicle --delay=$(delay) --colors=256 --loop $(DIRGIF) > $@
    echo $@ >> provide

clean:
    rm -f anime.gif provide

install-tools:
    sudo apt-get install gifsicle

.PHONY: all install-tools clean

The most commonly useful parameter, the delay between frames, is nicely documented at the top. I don't have to remember that the switch name is --delay or that the switch style --delay=60 is used. I simply change the number above until I get the result that I want.

Example 3: add a new recipe

As a sample scenario, assume you want to convert *.svg to *.png.

Step 1

An internet search leads to Stack Overflow and this command:

inkscape -z -e test.png -w 1024 -h 1024 test.svg

Navigate to the file(s) in dired and call make-it-so with ,. No default actions are available, so just type "to-png" and hit RET. The "to-" prefix signifies that this is a conversion, adapting the Makefile to this form:

# This is a template for the Makefile.
# Parameters should go in the upper half as:
#     width = 200
# and be referenced in the command as $(width)

# ____________________________________________

DIRSVG = $(shell dir *.svg)

DIRPNG = $(DIRSVG:.svg=.png)

all: clean Makefile $(DIRPNG)

%.png: %.svg
    echo "add command here"
    echo $@ >> provide

clean:
    rm -f *.png provide

# Insert the install command here.
# e.g. sudo apt-get install ffmpeg
install-tools:
    echo "No tools required"

.PHONY: all install-tools clean

If the action name doesn't have a "to-" prefix, the transformation is assumed to be e.g. "svg" -> "out.svg". You can change this of course by editing the Makefile.

Step 2

In case the command needs additional packages in order to work you might want to change echo "No tools required" to the appropriate package install instruction, e.g. sudo apt-get install inkscape.

When you're on a new system, this will serve as a reminder of what you should install in order for the Makefile to work. Simply call:

make install-tools

Step 3

Replace echo "add command here" with:

    inkscape -z -e $@ -w $(width) -h $(height) $^
  • The parameters width and height will go to the top of the Makefile, where they can be customized.

  • $@ refers to the output file, test.png in this case.

  • $^ refers to the input file, test.svg in this case.

That's it. You can see the final Makefile here. Test if the command works with f5 from the Makefile. If you're happy with it, call mis-finalize with C-, from dired. The Makefile will be saved for all future calls to make-it-so.

Outro

To summarize the advantages of make-it-so:

  • Write the recipe one time, never have to look up how to do the same thing a few months from now.
  • A chance to write the recipe zero times, if someone in the community has already done it and shared the recipe with you.
  • The Elisp layer takes care of hairy file names.
  • Parallel commands on multiple files, i.e. make -j8, are provided for free.

The most important usage tip: until you're sure that the command and the Makefile work properly make backups. In fact, make backups period. Happy hacking!

-1:-- Make it so&amp;#58 file1 -&gt; Makefile -&gt; file2 (Post)--L0--C0--February 24, 2017 11:00 PM

Got Emacs?: Emacs 25.2 RC1 out

The first release candidate for what will be the 25.2 release of Emacs is out. 
-1:-- Emacs 25.2 RC1 out (Post sivaram (noreply@blogger.com))--L0--C0--February 17, 2017 10:55 AM

My Acid Words: Displaying org-mode appointments in calendar

One neat feature of org-mode agenda is ability to display appointments in Emacs calendar. Sadly, this isn't obvious nor enabled by default - I discovered it accidentally by browsing through Emacs themes screenshots.

In screenshot below, you can see highlighted days with planned meetings and scheduled work in my calendar.

emacs-calendar

Setup is very easy. First, set calendar-mark-diary-entries-flag with:

(setq calendar-mark-diary-entries-flag t)

Then create $HOME/diary file, if not present, and add this line:

%%(org-diary)

Now in Emacs, open agenda view with (org-agenda) and open calendar with c; you will get highlighted all important dates. Alternatively, calling

M-x calendar

will essentially do the same (open calendar) with fewer strokes.

Reverse action will also work - to see what is scheduled for particular highlighted day, just point cursor to that day and hit key c - Emacs will open org-mode agenda view and place cursor under correct entry.

Using with appointments (appt)

In case you use org-mode with appointments to get visual reminders, be aware that calling (appt-activate 1) will run diary and making this call in your Emacs configuration will display diary window at Emacs startup, which I didn't like. To circumvent this behavior, appt-display-diary variable should be used.

In short, my appointments setup looks like this:

(add-hook 'org-finalize-agenda-hook
  (lambda ()
    (setq appt-message-warning-time 10        ;; warn 10 min in advance
          appt-display-diary nil              ;; do not display diary when (appt-activate) is called
          appt-display-mode-line t            ;; show in the modeline
          appt-display-format 'window         ;; display notification in window
          calendar-mark-diary-entries-flag t) ;; mark diary entries in calendar
    (org-agenda-to-appt)                      ;; copy all agenda schedule to appointments
    (appt-activate 1)))                       ;; active appt (appointment notification)
-1:-- Displaying org-mode appointments in calendar (Post)--L0--C0--February 15, 2017 11:00 PM

Grant Rettke: Asynchronous src_block Execution For Org-Babel

Via here:

ob-async enables asynchronous execution of org-babel src blocks

It works for any language.

-1:-- Asynchronous src_block Execution For Org-Babel (Post Grant)--L0--C0--February 15, 2017 06:53 PM

Chris Wellons: Asynchronous Requests from Emacs Dynamic Modules

A few months ago I had a discussion with Vladimir Kazanov about his Orgfuse project: a Python script that exposes an Emacs Org-mode document as a FUSE filesystem. It permits other programs to navigate the structure of an Org-mode document through the standard filesystem APIs. I suggested that, with the new dynamic modules in Emacs 25, Emacs itself could serve a FUSE filesystem. In fact, support for FUSE services in general could be an package of his own.

So that’s what he did: Elfuse. It’s an old joke that Emacs is an operating system, and here it is handling system calls.

However, there’s a tricky problem to solve, an issue also present my joystick module. Both modules handle asynchronous events — filesystem requests or joystick events — but Emacs runs the event loop and owns the main thread. The external events somehow need to feed into the main event loop. It’s even more difficult with FUSE because FUSE also wants control of its own thread for its own event loop. This requires Elfuse to spawn a dedicated FUSE thread and negotiate a request/response hand-off.

When a filesystem request or joystick event arrives, how does Emacs know to handle it? The simple and obvious solution is to poll the module from a timer.

struct queue requests;

emacs_value
Frequest_next(emacs_env *env, ptrdiff_t n, emacs_value *args, void *p)
{
    emacs_value next = Qnil;
    queue_lock(requests);
    if (queue_length(requests) > 0) {
        void *request = queue_pop(requests, env);
        next = env->make_user_ptr(env, fin_empty, request);
    }
    queue_unlock(request);
    return next;
}

And then ask Emacs to check the module every, say, 10ms:

(defun request--poll ()
  (let ((next (request-next)))
    (when next
      (request-handle next))))

(run-at-time 0 0.01 #'request--poll)

Blocking directly on the module’s event pump with Emacs’ thread would prevent Emacs from doing important things like, you know, being a text editor. The timer allows it to handle its own events uninterrupted. It gets the job done, but it’s far from perfect:

  1. It imposes an arbitrary latency to handling requests. Up to the poll period could pass before a request is handled.

  2. Polling the module 100 times per second is inefficient. Unless you really enjoy recharging your laptop, that’s no good.

The poll period is a sliding trade-off between latency and battery life. If only there was some mechanism to, ahem, signal the Emacs thread, informing it that a request is waiting…

SIGUSR1

Emacs Lisp programs can handle the POSIX SIGUSR1 and SIGUSR2 signals, which is exactly the mechanism we need. The interface is a “key” binding on special-event-map, the keymap that handles these kinds of events. When the signal arrives, Emacs queues it up for the main event loop.

(define-key special-event-map [sigusr1]
  (lambda ()
    (interactive)
    (request-handle (request-next))))

The module blocks on its own thread on its own event pump. When a request arrives, it queues the request, rings the bell for Emacs to come handle it (raise()), and waits on a semaphore. For illustration purposes, assume the module reads requests from and writes responses to a file descriptor, like a socket.

int event_fd = /* ... */;
struct request request;
sem_init(&request.sem, 0, 0);

for (;;) {
    /* Blocking read for request event */
    read(event_fd, &request.event, sizeof(request.event));

    /* Put request on the queue */
    queue_lock(requests);
    queue_push(requests, &request);
    queue_unlock(requests);
    raise(SIGUSR1);  // TODO: Should raise() go inside the lock?

    /* Wait for Emacs */
    while (sem_wait(&request.sem))
        ;

    /* Reply with Emacs' response */
    write(event_fd, &request.response, sizeof(request.response));
}

The sem_wait() is in a loop because signals will wake it up prematurely. In fact, it may even wake up due to its own signal on the line before. This is the only way this particular use of sem_wait() might fail, so there’s no need to check errno.

If there are multiple module threads making requests to the same global queue, the lock is necessary to protect the queue. The semaphore is only for blocking the thread until Emacs has finished writing its particular response. Each thread has its own semaphore.

When Emacs is done writing the response, it releases the module thread by incrementing the semaphore. It might look something like this:

emacs_value
Frequest_complete(emacs_env *env, ptrdiff_t n, emacs_value *args, void *p)
{
    struct request *request = env->get_user_ptr(env, args[0]);
    if (request)
        sem_post(&request->sem);
    return Qnil;
}

The top-level handler dispatches to the specific request handler, calling request-complete above when it’s done.

(defun request-handle (next)
  (condition-case e
      (cl-ecase (request-type next)
        (:open  (request-handle-open  next))
        (:close (request-handle-close next))
        (:read  (request-handle-read  next)))
    (error (request-respond-as-error next e)))
  (request-complete))

This SIGUSR1+semaphore mechanism is roughly how Elfuse currently processes requests.

Windows

Windows doesn’t have signals. This isn’t a problem for Elfuse since Windows doesn’t have FUSE either. Nor does it matter for Joymacs since XInput isn’t event-driven and always requires polling. But someday someone will need this mechanism for a dynamic module on Windows.

Fortunately there’s a solution: input language change events, WM_INPUTLANGCHANGE. It’s also on special-event-map:

(define-key special-event-map [language-change]
  (lambda ()
    (interactive)
    (request-process (request-next))))

Instead of raise() (or pthread_kill()), broadcast the window event with PostMessage(). Outside of invoking the language-change key binding, Emacs will ignore the event because WPARAM is 0 — it doesn’t belong to any particular window. We don’t really want to change the input language, after all.

PostMessageA(HWND_BROADCAST, WM_INPUTLANGCHANGE, 0, 0);

Naturally you’ll also need to replace the POSIX threading primitives with the Windows versions (CreateThread(), CreateSemaphore(), etc.). With a bit of abstraction in the right places, it should be pretty easy to support both POSIX and Windows in these asynchronous dynamic module events.

-1:-- Asynchronous Requests from Emacs Dynamic Modules (Post)--L0--C0--February 14, 2017 02:30 AM

Phil Hagelberg: in which four pieces are placed in a row

The other day my son and I were at a friend's house, and we were just on our way home. As we were leaving he saw they had the game Connect 4 and asked if we could play. Since we were on our way I told him, "We can't play the game now, but when we get home, we can program the game, and then play that." I wasn't sure exactly how this would work out, but I thought we'd have some fun on the way.

This isn't the first time I've adapted a physical game to a program with my kids. But since then I've done most of my games using LÖVE, the 2D Lua game framework along with Polywell, a text editor and development tool that runs in it. Polywell is roughly a port of Emacs, and I've found that the foundation it provides of buffers, modes, and keymaps is useful for all kinds of games. As a bonus, you can use the text editing features of Polywell to code the game from within the game itself, which makes experimentation and reloading seamless.

My son and I sat down and knocked out an implementation of Connect 4 pretty quickly using Polywell, and I thought it would be interesting to step through how it works since it can serve as a very succinct explanation for how to use Polywell.

local e = require("polywell")

local board = { {}, {}, {}, {}, {}, {}, {} }
local colors = {red={255,50,50},yellow={255,238,0}}
local turn = "yellow"

We start out by loading "polywell" and putting it in the e local (e for editor). Most of the game state is in the board table[1], which has an empty table for each column in it. The Connect 4 board has seven columns in which pieces can be dropped. It's a bit unusual, but we represent columns as lists of pieces from the bottom up, because the tokens are subject to gravity and fall to the bottom of the column they're placed in. Finally we set up colors which maps each player's color name to an RGB triplet and store the final bit of state (the current turn) in the turn local. So far so good!

local draw = function()
   for col=1,7 do
      for n,color in ipairs(board[col]) do
         local x,y = col * 75, 800 - n*75
         love.graphics.setColor(colors[color])
         love.graphics.circle("fill", x, y, 30)
      end
   end
end

Our draw function is very natural once you understand the unusual structure of the board; we simply loop over each column with an inner loop over each piece in the column. The piece is represented by n, its numeric position within the list of pieces, and its color. We calculate x and y from the col and n respectively and draw a colored circle for each piece from the bottom of the column upwards. This is basically the only place we use the LÖVE framework directly.

e.define_mode("connect4", nil, {draw=draw, read_only=true})

Using Polywell's define_mode function we create a "connect4" mode which will contain all the key bindings for the game. Modes in Polywell are assumed to be textual unless otherwise specified, but since our game is graphical we pass nil as the second argument because our mode does not inherit from any existing mode. For our third argument, we pass in our previously-defined draw function as the mode's draw property, overriding the default draw which simply displays the current mode's text. We also mark it as read_only to avoid accidentally inserting any text into the buffer.

e.bind("connect4", "escape", function() e.change_buffer("*console*") end)
e.bind("connect4", "backspace", function()
          for i=1,7 do lume.clear(board[i]) end
end)

Polywell's bind function allows us to attach a function to be called when a specific keystroke is pressed in a specific mode. In this case we say that escape will switch back to the Lua console while backspace will just clear each column in the board.

for key=1,7 do
   e.bind("connect4", tostring(key), function()
             local column = board[key]
             if(#column >= 6) then return end
             table.insert(column, turn)
             turn = turn == "red" and "yellow" or "red"
   end)
end

Almost done! Here's where the meat of the game is. We loop from 1 to 7, which is the number of columns in the game. For each column, we bind that number key to a function which grabs the corresponding column table from the board. It checks to make sure the column isn't full (each one can only hold 6 pieces) and if not it inserts the color of the current player into the column with table.insert. Then it changes the turn to the next player.

e.open(nil, "*connect4*", "connect4")

Finally it uses the open function to create a new buffer named "*connect4*" with "connect4" mode active. The first argument is nil because this buffer is not attached to the filesystem; it's a free-floating thing that doesn't get loaded or saved. You could leave this line out and Polywell would simply boot to a Lua console where you could invoke connect4 mode manually from there.

And that's it! 27 lines is all it took, and me and my son were off to the races playing the game. While we were writing it I kept him involved by asking each step of the way what we should do next. Once I wrote the draw function we were able to test it out by editing the board table directly using Lua code in the console. Our first pass of the number key function simply called table.insert, so once we tried it out he was able to point out which features were still missing, and I could ask leading questions which helped him piece together roughly what was needed to address those things.

Of course there's a lot more that Polywell can do, but it doesn't take much code to get a simple game going. Try it for yourself; you might have a lot of fun.


[1] Lua tables can be a bit confusing since they're a single data structure that can act both sequentially (as with board here which is basically used as a vector/array) or associatively (as with colors which acts like a map). The thing to remember is that the sequential/associative property is not inherent in the table but rather part of how it's used.

-1:-- in which four pieces are placed in a row (Post Phil Hagelberg)--L0--C0--February 12, 2017 11:15 PM

emacspeak: Audio Deja Vu: Audio Formatted Math On The Emacspeak Desktop


Audio Deja Vu: Audio Formatted Math On The Emacspeak Desktop

1 Overview

This article previews a new feature in the next Emacspeak release —
audio-formatted Mathematics using Aural CSS. Volker Sorge worked
at Google as a Visiting Scientist from Sep 2012 to August 2013, when
we implemented math
access in ChromeVox
— see this brief overview. Since leaving
Google, Volker has refactored and extended his work to create an Open
Source Speech-Rule-Engine implemented using NodeJS. This
speech-rule-engine can be used in many different environments;
Emacspeak leverages that work to enable audio-formatting and
interactive browsing of math content.



2 Overview Of Functionality

Math access on the Emacspeak desktop is implemented via module
emacspeak-maths.el — see js/node/Readme.org in the Emacspeak GitHub
repository for setup instructions.


Once loaded, module emacspeak-maths provides a Math Navigator that
implements the user interface for sending Math expressions to the
Speech-Rule-Engine, and for interactively browsing the resulting
structure. At each step of the interaction, Emacspeak receives math
expressions that have been annotated with Aural CSS and produces
audio-formatted output. The audio-formatted text can itself be
navigated in a special Spoken Math emacs buffer.


Module emacspeak-maths.el implements various affordances for
dispatching mathematical content to the Speech-Rule-Engine — see
usage examples in the next section.


3 Usage Examples

3.1 The Emacspeak Maths Navigator

  • The maths navigator can be invoked by pressing S-SPC (hold
    down Windows key and press SPC) — this runs the command emacspeak-maths-navigator/body.
  • Once invoked, the /Maths Navigator can be used to enter an
    expression to read.
  • Pressing SPC again prompts for the LaTeX math expression.
  • Pressing RET guesses the expression to read from the current context.
  • The arrow keys navigate the expression being read.
  • Pressing o switches to the Spoken Math buffer and exits the
    navigator.

See the relevant chapter in the online Emacspeak manual for details.


3.2 Math Content In LaTeX Documents

  1. Open a LaTeX document containing math content.
  2. Move point to a line containing mathematical markup.
  3. Press S-SPC RET to have that expression audio-formatted.
  4. Use arrow keys to navigate the resulting structure.
  5. Press any other key to exit the navigator.

3.3 Math Content On Wikipedia

  1. Open a Wikipedia page in the Emacs Web Wowser (EWW) that has
    mathematical content.
  2. Wikipedia displays math as images, with the alt-text giving the
    LaTeX representation.
  3. Navigate to some math content on the page, then press S-SPC
    a to speak that content — a is for alt.
  4. As an example, navigate to Wikipedia Math Example, locate math expressions on that page, then
    press S-SPC a.

3.4 Math Content From The Emacs Calculator

  1. The built-in Emacs Calculator (calc) provides many complex
    math functions including symbolic algebra.
  2. For my personal calc setup, see tvr/calc-prepare.el in the
    Emacspeak GitHub repo.
  3. This setting below sets up the Emacs Calculator to output results
    as LaTeX: (setq calc-language 'tex)
  4. With the above setting in effect, launch the emacs Calculator by
    pressing M-##.
  5. Press ' — to use algebraic mode — and enter sin(x).
  6. Press a t to get the Taylor series expansion of the above
    expression, and press x when prompted for the variable.
  7. This displays the Taylor Series expansion up to the desired
    number of terms — try 7 terms.
  8. Now, with Calc having shown the results as TeX, press S-SPC
    RET to browse this expression using the Maths Navigator.



4 And The Best Is Yet To Come

This is intentionally called an early preview because there is still
much that can be improved:


  1. Enhance the rule engine to infer and convey more semantics.
  2. Improved audio formatting rules to better present the available information.
  3. Update/tune the use of Aural CSS properties to best leverage
    today's TTS engines.
  4. Integrate math-reading functionality into more usage contexts in
    addition to the ones enumerated in this article.


5 References

  1. Youtube Video from early 2013 demonstrating Math Access in Chrome
  2. AllThings Digital outlining math access — published June 2013.
  3. Assets 2016 publication describing this work.
  4. js/node/aster-math-examples.tex Collection of math examples in
    LaTeX from AsTeR. Used to progressively improve speech-rules and
    the resulting audio-formatted output
  5. Speech-Rule-Engine on github.
  6. Speech-Rule-Engine in action: Accessible Maths in all browsers

Date: 2017-02-08 Wed 00:00

Author: T.V Raman


-1:-- Audio Deja Vu: Audio Formatted Math On The Emacspeak Desktop (Post T. V. Raman (noreply@blogger.com))--L0--C0--February 10, 2017 07:22 PM