String2 = 'But no highlighting for $Foo is this string.'  This is another case where the font-locking has to be context aware: we want it in a double-quoted string but not in a single-quoted string so the context of where the interpolated variable appears matters. As Fuco1 said in his original post, you can substitute a function for the normal regular expression controlling font-locking as long as the function has the same interface and returns as re-search-forward. Check out Fuco1’s post for how he solved the problem. If you, like Fuco1, have a refined sense of style in such matters, you can install his code and get his results yourself. -1:-- More Font-locking Fun from Fuco1 (Post jcs)--L0--C0--June 20, 2017 03:55 PM ## Pragmatic Emacs: Insert internal org-mode links the ivy way Org-mode is a fantastic way to organise information in simple text files. I often use internal links to other sections in a document for navigation, but I’ve found that there is not a great mechanism to quickly insert an internal link. I wanted an interface that would provide me a list of headlines in the document that I could use to select a link target, so I put together the functions below. These simple functions leverage the fantastic ivy and worf packages, so install them first. Then put the code below into your emacs config file. Then, invoking M-x bjm/worf-insert-internal-link provides an ivy completion interface for the list of headlines in the document. Once you select the headline you want as the link target, the link is inserted for you. ;; use ivy to insert a link to a heading in the current document ;; based on worf-goto (defun bjm/worf-insert-internal-link () "Use ivy to insert a link to a heading in the current org-mode' document. Code is based on worf-goto'." (interactive) (let ((cands (worf--goto-candidates))) (ivy-read "Heading: " cands :action 'bjm/worf-insert-internal-link-action))) (defun bjm/worf-insert-internal-link-action (x) "Insert link for bjm/worf-insert-internal-link'" ;; go to heading (save-excursion (goto-char (cdr x)) ;; store link (call-interactively 'org-store-link) ) ;; return to original point and insert link (org-insert-last-stored-link 1) ;; org-insert-last-stored-link adds a newline so delete this (delete-backward-char 1) )  -1:-- Insert internal org-mode links the ivy way (Post Ben Maughan)--L0--C0--June 20, 2017 10:25 AM ## Irreal: Xah's Tutorial on Text Properties Xah Lee has a new page out in his Emacs Lisp Tutorial that serves as a 10 minute introduction to text properties. Text properties are one of those things that you probably won’t need to fiddle with directly unless you are writing a (major or minor) mode but you often see them mentioned in such commands as buffer-substring-no-properties, which is a common function that anyone might use to write Elisp that manipulates text. So even if you don’t use them directly, it’s nice to know what they are and how they work. The tutorial just gives you a flavor of what you can do with properties but it links to the full documentation if you really want all the details. It’s pretty easy to deal with the properties, as you’ll see when you read the tutorial. I haven’t written about Lee’s tutorial for some time but I thought this new page was interesting and that others might enjoy it too. Lee has done a lot of work on the tutorial since I last mentioned it and it looks pretty good and is easy to navigate. One thing I especially like is that hovering over a function will pop up the doc string for that function so it’s easy to follow the action if an example uses a function you’re not familiar with. If you work off-line a lot or just want to help out, you can buy a copy of both the Emacs and Emacs Lisp tutorials for$25.

-1:-- Xah's Tutorial on Text Properties (Post jcs)--L0--C0--June 19, 2017 04:49 PM

## Raimon Grau: TIL: evil-buffer-regexps

So I have my evil-mode perfectly adapted to my workflow, activating or deactivating it by default depending on the major-mode, so that I don't get into normal mode on magit buffers, or sly-*, or eww.

BUT, there are some buffers which you cannot easily control, because they reuse some major mode where I usually want evil-normal, but not in those cases.

In my case, it's *sly-macroexpansion* and *sly-description* buffers. They are both "lisp-mode" buffers (for syntax highlighting purposes and such), but I want 'q' to quit them.   As they do not represent any file, I was out of luck binding modes to file extensions. (btw, here's some recent article talking bout the ways emacs chooses your major mode)

So trying to hack something using emacs hooks, I found that, in fact, evil has us covered, and provides a evil-buffer-regexps, that allows us to predefine modes on given buffer names.

(add-to-list 'evil-buffer-regexps             '("\\*sly-macroexpansion\\*" . emacs))

-1:-- TIL: evil-buffer-regexps (Post Raimon Grau (noreply@blogger.com))--L0--C0--June 19, 2017 03:21 PM

## sachachua: 2017-06-19 Emacs news

• Emacs Lisp:
• Emacs development:
• Org Mode:
• Coding:
• Other:
• New packages:

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-06-19 Emacs news (Post Sacha Chua)--L0--C0--June 19, 2017 05:24 AM

## Marcin Borkowski: Ways in which Emacs selects the major mode

It is well-known that Emacs can select the major mode of a file depending on the file extension. It is probably lesser-known that this is only the fourth (!) step of deciding which major mode to use. Consult the "Choosing modes" section of the Emacs manual for the details. Here, I’d like to mention one particular case where I needed to look there.
-1:-- Ways in which Emacs selects the major mode (Post)--L0--C0--June 17, 2017 04:21 AM

## Manuel Uberti: Keeping your .emacs.d clean

How often do you have a look at your .emacs.d directory? If you’re anything like me, not that often. It’s no wonder then that upon opening it I was horrified to see it cluttered with all sorts of files from all the packages I regularly use.

Jonas Bernoulli, of Magit fame, must be feeling similar concerns. Otherwise, why did he come up with a package like no-littering?

Installation is trivial, especially if you use the great use-package:

(use-package no-littering               ; Keep .emacs.d clean
:ensure t
:config
(require 'recentf)


No extra setup is required. Place this snippet somewhere at the beginning of your init.el file and you are set. Use Emacs for a while and then go back checking .emacs.d: nice, huh?

To be honest, I wiped out my .emacs.d directory, cloned my configuration from GitHub and started from fresh with no-littering installed. Too much, maybe, but I was eager to see how good this package is. And yes, it is good.

House-cleaning has never been so easy.

-1:-- Keeping your .emacs.d clean (Post)--L0--C0--June 17, 2017 12:00 AM

## Marcin Borkowski: smart-next-window-or-buffer

Some time ago, I wrote about an Emacs command I started to use to switch between windows (if there is more than one of them) or buffers (otherwise). While it has proven very useful, since then I started to use multiple frames. It turned out that my command wasn’t all that useful then: it couldn’t switch to a buffer in another frame. I then decided to bind f6 to next-multiframe-window from windmove.el, and it worked better. However, there was still one gotcha: sometimes I wanted it to switch to another window in the same frame, and it switched to another frame instead. Well, how to teach Emacs what I really wanted?
-1:-- smart-next-window-or-buffer (Post)--L0--C0--June 12, 2017 09:44 AM

## sachachua: 2017-06-12 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-06-12 Emacs news (Post Sacha Chua)--L0--C0--June 12, 2017 06:21 AM

## Pragmatic Emacs: To eww or not to eww

Recent Emacs versions include a decent text based web browser called eww. There is a good example configuration here. I found that I like using eww for some things, but at other times I want to use a full GUI web browser (I like Firefox).

I set eww to be my default browser in Emacs with

(setq browse-url-browser-function 'eww-browse-url)


but then I create some wrapper functions for times when I want to use my system default browser (i.e. Firefox).

In mu4e emails, hitting g will now open a URL in eww, but with the following lines I can use G to open in Firefox:

;; open link in firefox rather than eww
(defun bjm/mu4e-view-go-to-url-gui ()
"Wrapper for mu4e-view-go-to-url to use gui browser instead of eww"
(interactive)
(let ((browse-url-browser-function 'browse-url-default-browser))
(mu4e-view-go-to-url)))
;; bind it
(define-key mu4e-view-mode-map (kbd "G") 'bjm/mu4e-view-go-to-url-gui)


In elfeed, hitting b opens an article in eww if that is set to be the default Emacs browser. With the following lines I can hit B to open an article in Firefox. Note that I had to resort to calling the Mac open command to open the URL with the system default browser. On linux systems the xdg-open command should do the same thing.

;; browse article in gui browser instead of eww
(defun bjm/elfeed-show-visit-gui ()
"Wrapper for elfeed-show-visit to use gui browser instead of eww"
(interactive)
(let ((browse-url-generic-program "/usr/bin/open"))
(elfeed-show-visit t)))

(define-key elfeed-show-mode-map (kbd "B") 'bjm/elfeed-show-visit-gui)

-1:-- To eww or not to eww (Post Ben Maughan)--L0--C0--June 11, 2017 11:26 PM

## Martin R. Albrecht: Handling Email with Emacs

Like many other people, I write, receive and loath a lot of email. Writing it goes something like this:

1. Create a new draft,
2. figure out the right address to put into the To: field,
3. write “Hi <first name>”,
4. write the actual message,
5. attach the correct file (if any),
6. append “Cheers, Martin”.

Also, a lot of email is repetitive and boring but necessary, such as asking seminar speakers for their titles and abstracts, giving people advise on how to claim reimbursement when they visit Royal Holloway, responding to requests of people who’d like to pursue a PhD.

Here is my attempt to semi-automate some of the boring steps in Emacs.

## Plumbing

I use mbsync for syncing my e-mail to my local hard disk as I often work offline, e.g. during my commute or while working on airplanes.1 Mbsync does not speak IMAP IDLE, aka push notifications, so I use imapnotify for this; here’s my (sanitised) imapnotify config file:

var child_process = require('child_process');

function getStdout(cmd) {
var stdout = child_process.execSync(cmd);
return stdout.toString().trim();
}

exports.host = "imap.gmail.com";
exports.port = 993;
exports.tls = true;
exports.password = // whatever needs doing, e.g. call getStdout()
exports.onNewMailPost = "emacsclient  -e '(mu4e-update-index)'";
exports.boxes = [ "INBOX"];


I only need imapnotify in Emacs, so I use prodigy to start/stop it.

(use-package prodigy
:ensure t
:init (prodigy-define-tag
:name 'email
:ready-message "Checking Email using IMAP IDLE. Ctrl-C to shutdown.")
(prodigy-define-service
:name "imapnotify"
:command "imapnotify"
:args (list "-c" (expand-file-name ".config/imapnotify.gmail.js" (getenv "HOME")))
:tags '(email)
:kill-signal 'sigkill))


Once arrived, email is parsed by Mu which provides fast, powerful fulltext search. Finally, Mu4e provides that email client experience™ in Emacs.

On the other end, I’m not relying on Emacs’ built-in support for sending email but use opensmtpd.2 Using Emacs’ built-in functionality means that it will hang while sending email (due to lack of multithreading), especially on slow connections, which defeats the purpose of getting email out of the way quickly.

Mu shines at search, it’s fast and expressive. For example, to search for messages between 2 kilobytes and 2Mb, written in December 2009 with an attachment from Bill, search

size:2k..2m date:20091201..20093112 flag:attach from:bill


Below are some examples for how I use it. Other ideas can be to filter for your project students, by your course number etc.

(add-to-list
'mu4e-bookmarks
'("flag:unread NOT flag:trashed AND (flag:list OR from:trac@sagemath.org)"

'mu4e-bookmarks
'("flag:unread NOT flag:trashed AND NOT flag:list AND (maildir:\"/royal holloway\" OR maildir:/INBOX)"

'mu4e-bookmarks
'("mime:application/* AND NOT mime:application/pgp* AND (maildir:\"/royal holloway\" OR maildir:/INBOX)"
"Messages with attachments for me." ?d) t)

'mu4e-bookmarks
'("flag:flagged"
"Flagged messages" ?f) t)

'mu4e-bookmarks
'("(maildir:\"/[Google Mail]/.Sent Mail\" OR maildir:\"/royal holloway/.sent\") AND date:7d..now"
"Sent in last 7 days" ?s) t)


By default Mu’s search is REPL, i.e. you type a query, press <enter> and look at the results. Sometimes you want real-time updates as you type, e.g. to adapt your search quickly. In this case, helm-mu has you covered. Helm adds a generic search-as-you-type interface to Emacs, here’s a nice intro.

(use-package helm-mu
:ensure t
:config (progn
(bind-key "S" #'helm-mu mu4e-main-mode-map)))


By the way, enabling helm-follow-mode via C-c C-f allows to preview emails as you search.

Sometimes, you might want to file an email with some project notes to be able to find it later without any effort or you might want to refer to it directly from your TODO list. I use Org-Mode for my TODOs and notes. Mu4e comes with Org-Mode support which provides links for messages and search queries. First, enable it

(use-package org-mu4e


and then add some org-capture templates to make filing and email or creating a TODO based on an email easy:

(use-package org-capture
:bind ("<f9>" . org-capture)
:config (setq org-capture-templates
'(("r" "respond ro email (mu4e)"
:immediate-finish t
:prepend t)

("f" "file email (mu4e)"
:immediate-finish nil
:prepend nil))))


## Writing

First, let’s make finding that email address easier. For this, I want an automatically maintained database holding at least

1. first name,
2. last name and

which is then used for autocompletion as I type. “Automatically maintained“ here means that this database should be built from our email correspondence, similar to e.g. what Gmail does. Adding email addresses and whatever else is in the From: field to some database isn’t difficult per se and many clients do it. For example, Mu4e comes with this built-in.

However, there are a few different conventions out there for how people write names in a From: field, so this needs a bit of tidying up. For example, Royal Holloway likes “Lastname, Firstname (Year)” for students; some people like to YELL their LASTNAME and then write the first name; some people misspell their own name. The code below canonicalises this.

(defun malb/canonicalise-contact-name (name)
(let ((case-fold-search nil))
(setq name (or name ""))
(if (string-match-p "^[^ ]+@[^ ]+\.[^ ]" name)
""
(progn
(setq name (replace-regexp-in-string "^\$$.*\$$ [^ ]+@[^ ]+\.[^ ]" "\\1" name))
;; strip quotes
(setq name (replace-regexp-in-string "^\"\$$.*\$$\"" "\\1" name))
;; deal with YELL’d last names
(setq name (replace-regexp-in-string "^\$$\\<[[:upper:]]+\\>\$$ \$$.*\$$" "\\2 \\1" name))
;; Foo, Bar becomes Bar Foo
(setq name (replace-regexp-in-string "^\$$.*\$$, \$$[^ ]+\$$.*" "\\2 \\1" name))
;; look up names and replace from static table, TODO look this up by email
(setq name (or (cdr (assoc name malb/mu4e-name-replacements)) name))
))))

(defun malb/mu4e-contact-rewrite-function (contact)
(let* ((name (or (plist-get contact :name) ""))
(mail (plist-get contact :mail))
(case-fold-search nil))
(plist-put contact :name (malb/canonicalise-contact-name name))
contact))

(setq mu4e-contact-rewrite-function #'malb/mu4e-contact-rewrite-function)


Now that our addresses are canonicalised, I can use those to fill in a few more bits. Given an email starting with “To: John Doe <john@example.com>” there is no point in typing the name “John” again when I do the customary “Hi …,”. Here, YASnippet comes in. YASnippet is a templating system for Emacs inspired by TextMate, which allows to map short sequences of characters to other sequences of characters, potentially by asking for more user input and/or calling some arbitrary Emacs Lisp function. For example, here’s the template we use to advertise the ISG seminar

# -*- mode: snippet -*-
# name: Announce ISG Research Seminar
# key: isg-announce
# --
${1:Thu},$2 @ ${3:11:00} in${4:HLT2}: $5 --- When:$1, $2, 2016 @$3
Where:  $4 Why: Because… reasons! Who:$5 ($6) # Title #$0

# Abstract #

# Bio #

Cheers,
Lorenzo & Martin


and here’s my “hi” template

# -*- mode: snippet -*-
# name: Say "hi"
# key: Hi
# --
Hi ${1:(malb/yas-get-names-from-to-fields)},$0

Cheers,
Martin


Using this snippet, typing Hi<Tab> triggers email boilerplate to be inserted, with the cursor eventually placed in the position of $0. The name used in the greeting is computed using the following function: (defun malb/yas-get-names-from-fields (fields) (let (names ret name point-end-of-line (search-regexp (mapconcat (lambda (arg) (concat "^" arg ": ")) fields "\\|")) (case-fold-search nil)) (save-excursion (goto-char (point-min)) (while (re-search-forward search-regexp nil t) (save-excursion (setq point-end-of-line (re-search-forward "$")))
(setq name (buffer-substring-no-properties (point) point-end-of-line))
(setq name (split-string name "[^ ]+@[^ ]+," t " ")) ;; split on email@address,
(setq names (append names name)))
(dolist (name names)
(setq name (malb/canonicalise-contact-name name))
(if (string-match "\$$[^ ,]+\$$" name)
(progn
(setq name (match-string 1 name))
(setq name (capitalize name))
(if ret
(setq ret (concat ret ", " name))
(setq ret name)))))
(if ret ret "there"))))

(defun malb/yas-get-names-from-to-fields ()
(interactive)
(malb/yas-get-names-from-fields '("To")))


Of course, you can create much more elaborate snippets calling all kinds of functions to respond to all kinds of email. Once you created so many snippets that you’re at risk of loosing track, I recommend helm-yasnippet as a nice interactive interface for selecting the right snippet.

To simplify adding attachments — because traversing directory trees is boring — I wrote a small interface to Baloo, which is KDE’s version of OSX’s Spotlight, i.e. desktop search:

(defcustom helm-baloo-file-limit 100
"Limit number of entries returned by baloo to this number."
:group 'helm-baloo
:type '(integer :tag "Limit"))

(defun baloo-search (pattern)
(start-process "baloosearch" nil "baloosearch" (format "-l %d " helm-baloo-file-limit) pattern))

(defun helm-baloo-search ()
(baloo-search helm-pattern))

(defun helm-baloo-transform (cs)
(let '(helm-baloo-clean-up-regexp (rx (or
control
(seq "[0;31m" (+ (not (any "["))) "[0;0m")
"[0;32m"
"[0;0m")))
(mapcar (function
(lambda (c)
(replace-regexp-in-string
(rx (seq bol (+ space))) ""
(replace-regexp-in-string helm-baloo-clean-up-regexp "" c))))
cs)))

(defvar helm-source-baloo
(helm-build-async-source "Baloo"
:candidates-process #'helm-baloo-search
:candidate-transformer #'helm-baloo-transform
:action '(("Open" . (lambda (x) (find-file x)))
("Attach to Email" . (lambda (x) (mml-attach-file x))))))

(defun helm-baloo ()
(interactive)
(helm :sources helm-source-baloo
:buffer "*helm baloo*"))


The line ("Attach to Email" . (lambda (x) (mml-attach-file x)) adds an option to attach any file to an email by pressing <F2>. If you prefer good ol’ locate, you can add this option to helm-locate too:

(helm-add-action-to-source "Attach to Email" #'mml-attach-file helm-source-locate)


Finally, a few more nice-to-have tweaks:

• I write email in German and English and manually switching spell-checking dictionaries is not on; auto-dictionary-mode allows to pick the right dictionary automatically by looking for key words and their frequency like “the” or “der/die/das”.
• Footnotes in email can be quite handy.
• Typo-mode replace quotes and friends with their typographically correct counterparts because UTF-8 is a thing.
• LaTeX notation like \lambda gets replaced by $\lambda$ because, again, UTF-8 is a thing.
(add-hook 'message-mode-hook #'flyspell-mode)


## Footnotes:

1

GMail takes care of all sorting into folders aka labels.

2

Debian GNU/Linux comes with exim4 by default, which isn’t easy to configure. OpenSMTPD, on the other hand, is rather straightforward.

-1:-- Handling Email with Emacs (Post martinralbrecht)--L0--C0--June 09, 2017 04:13 PM

## Anything goes: Launch Emacs for Windows with Batch File using Emacs Configuration from Cygwin

I maintain a shared Emacs configuration under Linux and Cygwin. In Windows, I wanted to easily launch Emacs from the Desktop with the following goals.

• Create a shortcut in the taskbar that launches Emacs for Windows
• Have Emacs for Windows obey the Emacs configuration from Cygwin
• Avoid opening extra console windows

Some prerequisites,

I created a file called c:\cygwin64\emacs.bat with the following contents.
c:\cygwin64\bin\run bash.exe -c ~/dotfiles/bin/emacs.sh

The file ~/dotfiles/bin/emacs.sh is a shell script that sits in my Cygwin directory. It is a wrapper script that calls Emacs for Windows if I'm running Cygwin.

It is assumed that the default Emacs configuration sits in the ~/.emacs file under Cygwin.

Pin the c:\cygwin64\emacs.bat script to your task bar. See below if you do not know how to do this. Clicking on it will open Emacs for Windows without any intervening console windows.

References
-1:-- Launch Emacs for Windows with Batch File using Emacs Configuration from Cygwin (Post tsengf (noreply@blogger.com))--L0--C0--June 05, 2017 06:50 AM

## Emacs café: Indium 0.6 is out!

Indium – the JavaScript development environment for Emacs – version 0.6 has just been released!

This release brings a lot of improvements and polish:

Installation and update instructions can be found in the documentation. You can also check out the project on GitHub.

Many thanks to Tatrix for his contributions to this release!

-1:-- Indium 0.6 is out! (Post Nicolas Petton)--L0--C0--May 31, 2017 01:10 PM

## Chen Bin (redguardtoo): Enhance diff-mode with Ivy

My current job requires me to review the freelancer's patches and apply them to our code branch under Perforce control. Due to my client's security policy, the freelancer can only work on isolated sandbox environment and can't access our code base directly.

I need two steps to finish the task:

• Open the freelancer's patch in diff-mode
• Run diff-apply-hunk to apply the hunks interactively

The problem is diff-mode always ask me to specify the file to be patched.

I read the code of diff-apply-hunk. The logic of diff-apply-hunk is simple. It tries different algorithms to guess the right file to patch. When the algorithms fail, it calls API read-file-name to ask me to provide the file path manually. If right file is found, the algorithms will work again and read-file-name will never be used for other hunks.

Here is my solution. I can find the file to patch in recent opened files because I store all of them by (setq recentf-max-saved-items 2048). I plan to use ivy-read from Ivy to locate the file at first. If this step fails , I can still fall back on original API read-file-name.

Here is the code

(defvar ffip-read-file-name-hijacked-p nil)
(defun ffip-diff-apply-hunk (&optional reverse)
(interactive "P")
(unless recentf-mode (recentf-mode 1))
(cond
(file-name (file-name-nondirectory (nth 2 args)))
(cands (remove nil (mapcar (lambda (s) (if (string-match-p (format "%s$" file-name) s) s)) (mapcar #'substring-no-properties recentf-list)))) (rlt (ivy-read "Recentf: " cands))) (if rlt (setq ad-return-value rlt) rlt ad-doit))) (t ad-do-it))) (diff-apply-hunk reverse) (setq ffip-read-file-name-hijacked-p nil))  Please note ffip-diff-apply-hunk can replace diff-apply-hunk. BTW, I can edit the patch on the spot when applying hunks. Similar to the work flow of git add --patch. The solution is added into https://github.com/technomancy/find-file-in-project. -1:-- Enhance diff-mode with Ivy (Post Chen Bin)--L0--C0--May 30, 2017 12:29 PM ## Ben Simon: The surprisingly simple path to a foot powered emacs I finally got around to soldering the components that power my USB foot pedal: While it's hardly a polished build, it's currently working quite well. I've found that it's an essential accessory for navigating macOS. To be able to jump from monitor to monitor without moving my fingers from the home row is a joy. On the Windows side of things, I'd planned to use the pedal to enhance emacs. There were two barriers to this: first, I needed a good key stroke related problem to solve. I've been using emacs for so long that even inefficient key-strokes feel right. The second challenge was figuring out how to integrate the pedal into emacs's keymaps and such. I imagined having to wade through thousands of lines of elisp to figure out an esoteric solution. Turns out, I was way overthinking things. This article explained more than I needed to know about emacs key handling. It was this snippet that ultimately paved the way for a trivial implementation: In order to actually bind a key you must first tell Emacs what key you intend to use. Unfortunately there’s more than one way of representing keys in Emacs: as a string, or as a vector. We won’t concern ourselves with either, as we will use a handy macro built in to Emacs called kbd. The kbd macro translates a human-readable key into a format Emacs can understand. I had previously coded the foot pedal to send F8 whenever it was pressed. I hesitantly popped into the *scratch* buffer and evaluated the following: (global-set-key (kbd "<f8>") 'goto-line)  I pressed the foot pedal and emacs prompted me for a line to jump to. OK, fair enough. But surely setting the foot pedal up to act as a sort of prefix key would require some elisp-fu. After invoking global-unset-key on F8 I tried the following: (global-set-key (kbd "<f8> r") 'rgrep) (global-set-key (kbd "<f8> g") 'goto-line)  I pushed the pedal down and typed the letter 'r'. And just like that, emacs asked me what I wanted to search for. I tried the same with pushing the pedal followed by g. That worked to. Apparently kbd and global-set-key just do the right thing. So much for having to read mountains of elisp code. I was then left with my initial challenge: how did I actually want to use the pedal to be efficient? For now, I've decided that any command I regularly type M-x, I'll bind to the pedal plus another key. As you can guess, M-x rgrep and M-x goto-line are two common examples of this. I'll definitely be on the lookout for more interesting challenges to solve, but at least it's a start. Have any suggestions for how I can get put the foot pedal to use? Please drop me a comment below. -1:-- The surprisingly simple path to a foot powered emacs (Post Ben Simon (noreply@blogger.com))--L0--C0--May 24, 2017 06:49 PM ## Bryan Murdock: Facebook Should Split In Two Facebook has done wonders to get people creating and consuming content on the internet. However, Facebook has grown to the point where it has no competition and is no longer innovating in ways that benefit us. Facebook should split into Facebook the aggregator and Facebook the content hoster. You could talk about a third piece that is Facebook the content provider, which is for providing things like gifs, templates, memes, emoji, games, and other stuff like that. Because Facebook hasn't completely broken from open web standards those types of content providers already exist today. Aggregators would be where you go to set up your friend list and see your feed. It could look and feel like Facebook does now. It would have an open standard protocol that content hosters would use if they wanted to be aggregated. This could still be an add driven business, but subscription, self hosted, and DIY solutions could exist too. Content hosters could either charge a monthly hosting fee, or they could serve up their own adds. Self hosted and DIY solutions could also exist. The big benefit to this would of course be the competition. Since it's an open standard anyone could be a content host, and anyone could be an aggregator. To make extra sure there is competition, and this could come in a phase two after the initial splitting up of Facebook, there should be open standards for exporting and importing friends, follows, likes, etc. to and from aggregators, and open standards for importing and exporting content from the hosters. Speaking of follows and likes, there could also be aggregator aggregators (AAs). People could opt in to publicly and anonymously share their likes and follows and the AAs would consume those and report on trends that cross aggregator boundaries. Anonymity could be much more protected this way while still giving us that interesting information about what is trending. One tricky part of this is how do I as a content author only allow my friends to see certain posts of mine? It would have to be with encryption. My content provider could keep public keys of my friends and only my friends (well, their aggregators) would be able to decrypt my posts using my friends' private keys. I can see some challenges and holes in this, but it doesn't seem any worse overall than how Facebook protects privacy now. Open implementations and peer review could get us to better-than-Facebook privacy quickly. Facebook would ideally recognize their stagnation and initiate this split themselves. We as their user base can and should help them understand the importance of this. Hopefully it doesn't have to come down to government enforcement of anti-trust laws, but that could be a useful tool to apply here as well. -1:-- Facebook Should Split In Two (Post Bryan (noreply@blogger.com))--L0--C0--May 24, 2017 10:58 AM ## Chen Bin (redguardtoo): Firefox and Emacs For me, there is NO difference between Firefox and Emacs. They provide useful APIs, nothing more. Three years ago, I wrote Use firefox in Emacs way to demo how to convert Firefox into Emacs by Keynsail. A year ago I published Hello Ivy-mode, bye Helm to prove how powerful Ivy-mode is by using its API ivy-read. Keysnail has similar javascript API prompt.selector and it's as powerful as ivy-read if not more powerful. For example, you can insert below snippet into ~/.keysnail.js and press ",hh" or "C-c C-h" to query browse history: function searchHistory(evt, arg) { function timeSince(now, date) { var seconds = Math.floor((now - date) / 1000); var interval = Math.floor(seconds / 31536000); if (interval > 1) { return interval + " years"; } interval = Math.floor(seconds / 2592000); if (interval > 1) { return interval + " months"; } interval = Math.floor(seconds / 86400); if (interval > 1) { return interval + " days"; } interval = Math.floor(seconds / 3600); if (interval > 1) { return interval + " hours"; } interval = Math.floor(seconds / 60); if (interval > 1) { return interval + " minutes"; } return Math.floor(seconds) + " seconds"; } function searchWithKeyword(q) { var collection = (function() { //search option var options = PlacesUtils.history.getNewQueryOptions(); options.maxResults = 4096; options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY; //options.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_FRECENCY_DESCENDING; options.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING; options.includeHidden = true; //search query var query = PlacesUtils.history.getNewQuery(); // read keyworld if(q && q !== '') { query.searchTerms = q; } var result = PlacesUtils.history.executeQuery(query, options); var root = result.root; var collection = []; var now = new Date().getTime(); var siteNode; root.containerOpen = true; for (var i = 0; i < root.childCount; i++) { // siteNode => nsINavHistoryResultNode siteNode = root.getChild(i); collection.push([siteNode.icon,siteNode.title,siteNode.uri, siteNode.time/1000]); } collection.sort(function(a, b) { return b[3]-a[3]; }); // reformat the time for (i = 0; i < collection.length; i++) { collection[i][3] = timeSince(now, collection[i][3]) + ' ago'; } root.containerOpen = false; return collection; })(); prompt.selector({ message : "Search history"+ (q && q !== ''? (' @'+q +':') : ':' ), collection : collection, flags : [ICON | IGNORE, 0, 0, 0], header : ["Title", "Url", "Last visited"], width : [30, 60, 10], callback: function (i) { if (i >= 0) { openUILinkIn(collection[i][2], "tab"); } }, onFinish: function() { gBrowser.focus(); _content.focus(); } }); } prompt.finish(true); prompt.read('Keyword to search history?', searchWithKeyword, null, null, null, 0, "history_search"); // searchWithKeyword('test'); } key.setViewKey([',', 'h', 'h'], searchHistory, "Search history"); key.setGlobalKey(['C-c', 'C-h'], searchHistory, "Search history");  Here is my complete .keysnail.js. -1:-- Firefox and Emacs (Post Chen Bin)--L0--C0--May 23, 2017 12:24 PM ## Alex Schroeder: Emacs Wiki Down Sadly it seems that Emacs Wiki is down. Currently Nic Ferrier is paying for the servers, so I sent him an email but haven’t heard back. So I’m thinking of resurrecting the site on my own servers. I still remember the fiasco that started with 2014-12-18 Emacs Wiki Migration. These are my notes. Perhaps they’re useful in case I have to restore another backup, or they might be useful to you if you want to fork Emacs Wiki. First, restore the backups from Chile provided by zeus. Thanks, man! rsync -az kensanata@theshire.emacs.cl:emacswiki.org . rsync -az kensanata@theshire.emacs.cl:emacswiki . I want to run the script from my Mojolicious Toadfarm. I added the following lines to my Toadfarm setup: # emacswiki.org mount "$farm/emacswiki.pl" => {
"Host" => qr{^emacswiki\.org:8080$}, mount_point => '/wiki', }; And this is the Mojolicious CGI Plugin wrapper, emacswiki.pl: #! /usr/bin/env perl use Mojolicious::Lite; plugin CGI => { support_semicolon_in_query_string => 1, }; plugin CGI => { route => '/', script => '/home/alex/farm/wiki.pl', # not necessary errlog => '/home/alex/farm/emacswiki.log', run => \&OddMuse::DoWikiRequest, before => sub { no warnings;$OddMuse::RunCGI = 0;
$OddMuse::DataDir = '/home/alex/emacswiki'; require '/home/alex/farm/wiki.pl'; }, }; app->start; In order for this to work, I need an Apache site. I created /etc/apache2/sites-available/500-emacswiki.org.conf with the following: <VirtualHost *:80> ServerName emacswiki.org ServerAlias www.emacswiki.org Redirect permanent / https://emacswiki.org/ </VirtualHost> <VirtualHost *:443> ServerAdmin alex@emacswiki.org ServerName emacswiki.org ServerAlias www.emacswiki.org DocumentRoot /home/alex/emacswiki.org <Directory /home/alex/emacswiki.org> Options ExecCGI Includes Indexes MultiViews SymLinksIfOwnerMatch # legacy CGI scripts like info-ref.pl AddHandler cgi-script .pl AllowOverride All Require all granted </Directory> SSLEngine on SSLCertificateFile /etc/letsencrypt.sh/certs/emacswiki.org/cert.pem SSLCertificateKeyFile /etc/letsencrypt.sh/certs/emacswiki.org/privkey.pem SSLCertificateChainFile /etc/letsencrypt.sh/certs/emacswiki.org/chain.pem SSLVerifyClient None ProxyPass /wiki http://emacswiki.org:8080/wiki ProxyPass /mojo http://emacswiki.org:8080/mojo </VirtualHost> I remove all the *.pl files except for info-ref.pl in the emacswiki.org directory. Reloded the farm using ./farm reload. Check the log file for Mounting emacswiki with conditions. Activating the site using sudo a2ensite 500-emacswiki.org. Check the config using sudo apachectl configtest. Oops! This is an obvious erorr, of course: SSLCertificateFile: file '/etc/letsencrypt.sh/certs/emacswiki.org/cert.pem' does not exist or is empty. I need to get the SSL certificates, too. I added emacswiki.org www.emacswiki.org to /etc/letsencrypt.sh/domains.txt and ran /etc/letsencrypt.sh/letsencrypt.sh -c but that doesn’t work. I guess it doesn’t work because the name emacswiki.org still points to the old server. I guess for the moment I’ll try to do without HTTPS. So this is what I’ll be using instead for the site: <VirtualHost *:80> ServerName emacswiki.org ServerAlias www.emacswiki.org ServerAdmin alex@emacswiki.org DocumentRoot /home/alex/emacswiki.org <Directory /home/alex/emacswiki.org> Options ExecCGI Includes Indexes MultiViews SymLinksIfOwnerMatch # legacy CGI scripts like info-ref.pl AddHandler cgi-script .pl AllowOverride All Require all granted </Directory> ProxyPass /emacs http://emacswiki.org:8080/wiki ProxyPass /wiki http://emacswiki.org:8080/wiki ProxyPass /mojo http://emacswiki.org:8080/mojo </VirtualHost> Now sudo apachectl configtest says Syntax OK. Reloaded Apache using sudo service apache2 reload. Added a line to my /etc/hosts file: 192.71.233.105 emacswiki.org Testing w3m http://emacswiki.org/wiki and w3m http://emacswiki.org/wiki seems to work! Better make the wiki read-only: touch ~/emacswiki/noedit. Following links doesn’t work. w3m http://www.emacswiki.org/emacs/HowToNavigate tells me: Can't load http://www.emacswiki.org/emacs/HowToNavigate. The problem is that Apache has www.emacswiki.org as a server alias, but the Toadfarm only listens for emacswiki.org. Change that: # emacswiki.org mount "$farm/emacswiki.pl" => {
"Host" => qr{^(www\.)?emacswiki\.org:8080$}, mount_point => '/wiki', }; And reload: ./farm reload. That didn’t work. Hah, of course not. I need to add www.emacswiki.org to my /etc/hosts, of course! Now it works. OK, next problem: Why does w3m http://www.emacswiki.org/ give me the directory listing? Surely I’m missing my .htaccess file. Is it not being read? The /var/log/apache2/error.log file has not suspicious. Well, it does mention something about the emacswiki.org/rss directory but I just deleted it. Are the permissions wrong? I did a chmod g-w .htaccess just to be sure and now it says: -rw-r--r-- 1 alex alex 1955 May 29 2016 emacswiki.org/.htaccess This looks correct to me. In there, it says DirectoryIndex emacs.pl. Ah. That might be a problem because I removed that script. Changing that to DirectoryIndex emacs did the job! OK, so anybody who has access to their own /etc/hosts file can now access a read-only copy of the site. Here’s what I have planned: 1. change the DNS entry ✓ 2. see how the site explodes 🔥🔥🔥 3. add HTTPS When I tried to add a News page, I noticed that I was unable to get the wiki back into writeable mode. I had to remove the noedit file I had created earlier using rm ~/emacswiki/noedit. Then, when I tried to save, the wiki complained about some page that looked like spam not being readable and I figured that the page index must have been out of sync so I simply removed it using rm ~/emacswiki/pageidx. And finally I recreated the lock using touch ~/emacswiki/noedit. OK, now I’m waiting for the DNS change to spread and watching my Munin graphs. Also, all the people with HTTPS bookmarks will get errors like the following: Bad cert ident from emacswiki.org: dNSName=alexschroeder.ch rpg.alexschroeder.ch www.alexschroeder.ch : accept? (y/n). That’s because emacswiki.org is currently longer listening on port 443 and the default site is alexschroeder.ch. Oh well! In a few hours I’m hoping that Let’s Encrypt will allow me to regenerate certificates for Emacs Wiki and then we’ll move to HTTPS. Hours later, I checked again and HTTP access was working. So I ran sudo /etc/letsencrypt.sh/letsencrypt.sh -c to get the certificates and this time it worked. I reverted the changes to the site config file /etc/apache2/sites-available/500-emacswiki.org.conf and we’re no using this: <VirtualHost *:80> ServerName emacswiki.org ServerAlias www.emacswiki.org Redirect permanent / https://emacswiki.org/ </VirtualHost> <VirtualHost *:443> ServerAdmin alex@emacswiki.org ServerName emacswiki.org ServerAlias www.emacswiki.org DocumentRoot /home/alex/emacswiki.org <Directory /home/alex/emacswiki.org> Options ExecCGI Includes Indexes MultiViews SymLinksIfOwnerMatch # legacy CGI scripts like info-ref.pl AddHandler cgi-script .pl AllowOverride All Require all granted </Directory> SSLEngine on SSLCertificateFile /etc/letsencrypt.sh/certs/emacswiki.org/cert.pem SSLCertificateKeyFile /etc/letsencrypt.sh/certs/emacswiki.org/privkey.pem SSLCertificateChainFile /etc/letsencrypt.sh/certs/emacswiki.org/chain.pem SSLVerifyClient None ProxyPass /emacs http://emacswiki.org:8080/wiki ProxyPass /wiki http://emacswiki.org:8080/wiki ProxyPass /mojo http://emacswiki.org:8080/mojo </VirtualHost> Notice that both /emacs and /wiki will work. Is this a bad idea? sudo apachectl configtest says the changes are good and so I ran sudo service apache2 reload. Everthing seems to be working! What about load? It’s definitely going up! OK, time to read up on mod_cache. I think I want something like the following: # Turn on caching CacheSocache shmcb CacheSocacheMaxSize 102400 <Location "/emacs"> CacheEnable socache </Location> Well, before diving into this, I think we should just monitor how load develops over the next few hours. A few hours later it would seem to me that there are no open issues so there is no need for extra caching. And that also means, I can try and make the website editable again. Let’s see, what else do we need to check? 1. does git work? 2. what about cronjobs? As for git, this is simple. I created the page 2017-05-18 and I expect to see it on the emacsmirror master branch. Sadly, it isn’t there. Why not? Let’s take a look: alex@sibirocobombus:~/emacswiki/git$ git log
commit a08f867084896e9892d148f76a54976166cd75db
Author: Alex Schroeder <anybody@emacswiki.org>
Date:   Thu May 18 13:56:01 2017 +0200

Backup site!

Oops! Apparently, the git repository wasn’t checked out. It makes sense, actually. But now I need to fix this. git remote -v shows no remotes. Let’s add it, and fetch data. This works because my public key is already part of the emacswirror org on GitHub.

git remote add origin git@github.com:emacsmirror/emacswiki.org.git
git fetch
git branch -m master temp
git checkout master

At this point it should tell you Branch master set up to track remote branch master from origin.

git cherry-pick a08f86
git push
git branch -D temp

OK. Time to test it! In order to be able to save, I now have to change the site URL in the config file back to HTTPS. It should read

my \$root = "https://www.emacswiki.org";

I made the page edit and that seems to do the trick. git log in the git directory lists the new edit.

This brings me to the next part: cron jobs. Somebody has to push those commits, right?

1. I added emacswiki and emacswiki.org to the shell script that uses rsync to store daily backups in Chile. Thanks again, zeus!
2. I found an old emacs-git-update in my bin directory and added an appropriate entry to my crontab using crontab -e.
3. I found an old maintain-emacswiki in my bin directory, fixed it, and also added it to crontab. I definitely need to check the maintenance page a few times over the next few days.
4. I found an old update-ell in my bin directory and decided to check the XML file referenced. The timestamp says Wed 24 Dec 2014 11:36:00 GMT so I think it’s safe to say that this won’t be required anymore.
5. I did not find a copy of the emacs-elisp-area script. I checked the code in my config file and now I remember: this job used to call the expensive Elisp Area URLs and save the result to disk, and then URL rewriting made sure that the Elisp Area URLs called from the web would read those files instead. I just tried those links (”Alphabetical list of all Elisp libraries on this Wiki” with and without context, and “Chronological list of all Elisp libraries on this Wiki”) and it seems to work just fine. It takes a few seconds, but nothing terrible. I’ll say that this won’t be required anymore.
6. I found an old copy of emacs-rss in my bin directory. That one precomputes some resource intensive RSS feeds. I should definitely get those back into working condition. When I run it, the four files are generated, and they’re the four RSS feed advertised in the HTML of the wiki, so that’s great.

And that’s all the jobs I found in an old crontab file!

Current status, one day later:

The only suspicious thing is the spike around 2:30 in the morning. But the explanation might be simple enough, looking at my crontab:

#m   h  dom mon dow   command
02  5  *   *   *     /home/alex/bin/maintain-campaignwiki
47 4,16 *  *   *     /home/alex/bin/backup
28  4  *   *   *     /home/alex/bin/subscriptions
14  3  *   *   *     /home/alex/bin/emacs-git-update
32  2  *   *   *     /home/alex/bin/maintain-emacswiki

At 2:32, the maintenance job runs. The curl output is available in the maintenance directory:

--2017-05-19 02:32:01--  https://www.emacswiki.org/emacs
Resolving www.emacswiki.org (www.emacswiki.org)... 192.71.233.105
Connecting to www.emacswiki.org (www.emacswiki.org)|192.71.233.105|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘/home/alex/emacswiki.org/maintenance/last.html’

0K .......... .......... .......... .......... .......... 43.1K
50K .......... .......... .......... .......... .......... 11.3K
100K .......... .......... .......... .......... .......... 3.66K
150K .......... .......... .......... .......... .......... 21.3K
200K .......... .......... .......... .......... .......... 35.7K
250K .......... .......... .......... .......... .......... 7.86K
300K .......... .......... .......... .......... .......... 12.4K
350K .......... .......... .......... .......... .......... 22.8K
400K .......... .......... .......... .......... .......... 19.3K
450K .......... .......... .......... .......... .......... 3.64K
500K .......... .......... .......... .......... .......... 5.91K
550K .......... .......... .......... .......... .......... 14.6K
600K .......... .......... .......... .......... .......... 10.3K
650K .......... .......... .......... .......... .......... 15.4K
700K .......... .......... .......... .......... .......... 20.5K
750K .......... .......... .......... .......... .......... 15.3K
800K .......... .......... .......... .......... .......... 15.3K
850K .......... .......... .......... .......... .......... 15.4K
900K .......... .......... .......... ......                18.5K=86s

2017-05-19 02:34:03 (10.9 KB/s) - ‘/home/alex/emacswiki.org/maintenance/last.html’ saved [959329]

I’m guessing that these two minutes are causing the spike.

When I did some testing with the CSS, I ran into problems. If you choose a different theme via the CSS page, it gets stored in a cookie. Cookies are specific to a site, and so cookies set on http://emacswiki.org, https://emacswiki.org, http://www.emacswiki.org and https://www.emacswiki.org are separate from each other. This will not do. I’ve now changed the Apache config file to create the appropriate redirections. At the same time, I wanted to clean up the https://www.emacswiki.org/wiki vs. https://www.emacswiki.org/emacs situation.

<VirtualHost *:80>
ServerName www.emacswiki.org
ServerAlias emacswiki.org
Redirect permanent / https://www.emacswiki.org/
</VirtualHost>
<VirtualHost *:443>
ServerName emacswiki.org
Redirect permanent / https://www.emacswiki.org/
SSLEngine on
SSLCertificateFile      /etc/letsencrypt.sh/certs/emacswiki.org/cert.pem
SSLCertificateKeyFile   /etc/letsencrypt.sh/certs/emacswiki.org/privkey.pem
SSLCertificateChainFile /etc/letsencrypt.sh/certs/emacswiki.org/chain.pem
SSLVerifyClient None
</VirtualHost>
<VirtualHost *:443>
ServerName www.emacswiki.org
DocumentRoot /home/alex/emacswiki.org
<Directory /home/alex/emacswiki.org>
Options ExecCGI Includes Indexes MultiViews SymLinksIfOwnerMatch
# legacy CGI scripts like info-ref.pl
AllowOverride All
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile      /etc/letsencrypt.sh/certs/emacswiki.org/cert.pem
SSLCertificateKeyFile   /etc/letsencrypt.sh/certs/emacswiki.org/privkey.pem
SSLCertificateChainFile /etc/letsencrypt.sh/certs/emacswiki.org/chain.pem
SSLVerifyClient None
Redirect permanent /wiki    https://www.emacswiki.org/emacs
ProxyPass /emacs            http://emacswiki.org:8080/wiki
ProxyPass /mojo             http://emacswiki.org:8080/mojo
</VirtualHost>

I wonder whether it’s important to prevent outside access to http://emacswiki.org:8080/wiki. I see no problem?

Tags:

-1:-- Emacs Wiki Down (Post)--L0--C0--May 18, 2017 11:24 AM

## Matthias Pfeifer: Emacs memory consumption

The Emacs built-in command (garbage-collect) gives detailed information about the data structures that currently consume memory. It is propably not the most usefull information but I wanted to collect the data and plot it. I started with writing functions to access the list returned from (garbage-collect): (defsubst get-mem-conses (mi) (let ((data (nth 0 mi))) (/ […]
-1:-- Emacs memory consumption (Post Matthias)--L0--C0--May 17, 2017 09:57 AM

## emacshorrors: The Dude Abides

While crafting another patch for cc-mode, I stumbled upon the following:

;; RMS says don't make these the default.
;; (April 2006): RMS has now approved these commands as defaults.
(unless (memq 'argumentative-bod-function c-emacs-features)
(define-key c-mode-base-map "\e\C-a"    'c-beginning-of-defun)
(define-key c-mode-base-map "\e\C-e"    'c-end-of-defun))


I’ve seen this kind of thing before, but it keeps puzzling me. Why would you:

• Put a comment there about not making the following a default
• Put a clarifying comment how these have been approved as defaults now

Any other project I’m involved in would immediately remove that commentary. Emacs is the only one where suggesting such drastic action would yield a lengthy bikeshedding discussion about the merits of pre-VCS traditions and how keeping them will toughen up whoever may join in the collaborative development effort. Yes, seriously.

-1:-- The Dude Abides (Post Vasilij Schneidermann)--L0--C0--May 15, 2017 07:59 PM

## Phil Hagelberg: in which actors simulate a protocol

I've been on a bit of a yak shave recently on Bussard, my spaceflight programming adventure game. The game relies pretty heavily on simulating various computer systems, from your own craft to space stations, portals, rovers, and other craft. It naturally needs to simulate communications between all these.

I started with a pretty simple method of having each connection spin up its own coroutine running its own sandboxed session. Space station sessions run smash, a vaguely bash-like shell in a faux-unix, while connecting to a portal triggers a small lisp script to check for clearance and gradually activate the gateway sequence. The main loop would allow each session's coroutine a slice of time for each update tick, but a badly-behaved script could make the frame rate suffer. (Coroutines, you will remember, are a form of cooperative multitasking; not only do they not allow more than one thing to literally be running at the same time, but handing control off must be done explicitly.) Also input and output was handled in a pretty ad-hoc method where Lua tables were used as channels to send strings to and from these session coroutines. But most problematic of all was the fact that there wasn't any uniformity or regularity in the implementations of the various sessions.

The next big feature I wanted to add was the ability to deploy rovers from your ship and SSH into them to control their movements or reprogram them. But I really didn't want to add a third half-baked session type; I needed all the different implementations to conform to a single interface. This required some rethinking.

The codebase is written primarily in Lua, but not just any Lua—it uses the LÖVE framework. While Lua's concurrency options are very limited, LÖVE offers true OS threads which run independently of each other. Now of course LÖVE can't magically change the semantics of Lua—these threads are technically in the same process but cannot communicate directly. All communication happens over channels (aka queues) which allow copies of data to be shared, but not actual state.

While these limitations could be annoying in some cases, they turn out to be a perfect fit for simulating communications between separate computer systems. Moving to threads allows for much more complex programs to run on stations, portals, rovers, etc without adversely affecting performance of the game.

Each world has a server thread with a pair of input/output channels that gets started when you enter that world's star system. Upon a successful login, a thread is created for that specific session, which also gets its own stdin channel. Input from the main thread's SSH client gets routed from the server thread to the stdin channel of each specific session. Each OS implementation can provide its own implementation of what a session thread looks like, but they all exchange stdin and stdout messages over channels. Interactive sessions will typically run a shell like smash or a repl, and their thread parks on stdin:demand(), waiting until the main thread has some input to send along.

This works great for regular input and output, but sometimes it's necessary for the OS thread to make state changes to tables in the main thread, such as the cargo script for buying and selling. Time to build an RPC mechanism! I created a whitelist table of all functions which should be exposed to code running in a session thread over RPC. Each of these is exposed as a shim function in the session's sandbox:

local add_rpc = function(sandbox, name)
sandbox[name] = function(...)
output:push({op="rpc", fn=name, args={...}, chan=chan})
local response = chan:demand()
if(response[1] == "_error") then
table.remove(response, 1)
error(unpack(response))
else
return unpack(response)
end
end
end

When the shim function is called it sends an op="rpc" table with a new throwaway channel (used only for communicating the return value), and sends it back over the output channel. The main thread picks this up, looks up the function in the rpcs table, and sends a message back over the response channel with the return value. This same RPC mechanism works equally well for scripts on space stations as it does for the portal control script, and a similar variation (but going the other direction) allows the SSH client to implement tab completion by making an RPC call to get completion targets.

They're not perfect, but the mechanisms LÖVE offers for concurrency have been a great fit in this particular case.

-1:-- in which actors simulate a protocol (Post Phil Hagelberg)--L0--C0--May 14, 2017 09:01 PM

## Emacs café: How to find all unused functions in JS buffers

The real power of Emacs lies in its extensibility. To be able to quickly hack some Elisp together to fix a specific problem right in your development environment is something quite unique to Emacs, and it makes it stand apart from other text editors.

I’m working on a fairly large JavaScript code base for which maintenance can sometimes be an issue.

Yesterday I wanted to quickly find all function definitions in a JavaScript file that were not referenced anymore in the project, so I decided to hack some Elisp to do that.

## What do we already have?

Let’s see what building blocks are already available.

xref-js2 makes it easy to find all references to a specific function within a project, and js2-mode exposes an AST that can be visited.

All in all, what I want to achieve shouldn’t be too hard to implement!

## First steps

I’m calling my small package js2-unused, so all functions and variables will have that prefix.

We’ll need some packages along the way, so let’s require them:

The first step is to find all function definitions within the current buffer. JS2-mode has a function js2-visit-ast that makes it really easy to traverse the entire AST tree.

We can first define a variable that will hold all function definition names that we find:

Now let’s traverse the AST and find all function definitions. We want to find:

• all assignments that assign to a function;
• all function declarations that are named (skipping anonymous functions).

## Finding references using xref-js2

Now that we can find and store all function names in a list, let’s use xref-js2 to filter the ones that are never referenced. If we find unreferenced functions, we simply display a message listing them.

## Conclusion

That’s it! In ~30 lines we can now find unreferenced functions in any JS file. Sure, the code is not perfect, far from it, but it was hacked together in 10 minutes and gets the job done.

Quickly writing some lisp code to fix a specific problem is something I do very often. Most of the time, it’s code I throw away as soon as the task is completed, but from time to time it’s something generic enough to be reused later, in which case I save it in my emacs.d, or make a proper package out of it.

If you find this feature useful, you can grab it from my emacs.d.

-1:-- How to find all unused functions in JS buffers (Post Nicolas Petton)--L0--C0--May 12, 2017 12:43 PM

## Timo Geusch: RTFM, or how to make unnecessary work for yourself editing inf-mongo

Turns out I made some unnecessary “work” for myself when I tried to add support for command history to inf-mongo. As Mickey over at Mastering Emacs points out in a blog post, comint mode already comes with M-n and M-p Read More

The post RTFM, or how to make unnecessary work for yourself editing inf-mongo appeared first on The Lone C++ Coder's Blog.

-1:-- RTFM, or how to make unnecessary work for yourself editing inf-mongo (Post Timo Geusch)--L0--C0--May 10, 2017 01:31 AM

## Timo Geusch: Extending inf-mongo to support scrolling through command history

I’m spending a lot of time in the MongoDB shell at the moment, so of course I went to see if someone had built an Emacs mode to support the MongoDB shell. Google very quickly pointed me at endofunky’s inf-mongo Read More

The post Extending inf-mongo to support scrolling through command history appeared first on The Lone C++ Coder's Blog.

-1:-- Extending inf-mongo to support scrolling through command history (Post Timo Geusch)--L0--C0--May 08, 2017 03:30 AM

# Hidden abstractions in the Diamond Kata

The other day my colleagues and I were doing the “Diamond Kata”. If you haven’t heard about code katas yet: it’s a coding exercise you’re supposed to do repeatedly in order to hone your skills. Each time, you might want to try different approaches, different programming languages or coding disciplines. I found the Diamond Kata interesting in its own right, let me tell you why.

The Diamond Kata is giving you a seemingly simple task: write code that outputs text in a diamond shape. The edges consist of letters, starting with “A”. The last letter is given as an argument and also determines the size of the diamond. The diamond for A⇒B looks like this:

 A
B B
A


The diamond for A⇒D would look like this:

   A
B B
C   C
D     D
C   C
B B
A


Looks pretty simple, right?

## A solution

I’m going to present a solution in ruby. Let’s write some end-to-end tests first:

class TestDiamond < Minitest::Test
def test_end_to_end
assert_equal <<-EOS, Diamond.new("A").to_s
A
EOS

assert_equal <<-EOS, Diamond.new("B").to_s
A
B B
A
EOS

assert_equal <<-EOS, Diamond.new("C").to_s
A
B B
C   C
B B
A
EOS
end
end


That was easy. So how are we going to solve this? Let’s start top down. We need to create the Diamond class and Diamond#to_s first. The string returned will be a concatenation of all the lines.

Diamond = Struct.new(:last) do
def to_s
lines.join
end

private

def lines
[] # ???
end
end


There’s only ever to be the same letter on every line and lines with the same letter look exactly alike. So we just need to figure out the right sequence of letters and have a method for creating the corresponding line. Let’s work on getting the sequence of letters right.

class TestDiamond < Minitest::Test
# [...]
def test_letters
assert_equal "A".chars, Diamond.new("A").letters
assert_equal "ABA".chars, Diamond.new("B").letters
assert_equal "ABCBA".chars, Diamond.new("C").letters
end
end

Diamond = Struct.new(:last) do
# [...]
def lines
letters.map(&method(:line_for))
end

def letters
(FIRST...last).to_a + (FIRST..last).to_a.reverse
end

def line_for(letter)
"" # ???
end
end


Well, this will do the job. Now on to implementing #line_for which will construct the string for one line. The tip and the bottom of the diamond are special as they only print one letter. For everything else, there will be some outer padding, repeated left and right, and some inner padding. We will need to do some ugly arithmetic with letters.

class TestDiamond < Minitest::Test
# [...]
def test_line_for
assert_equal "A\n", Diamond.new("A").line_for("A")
assert_equal " A \n", Diamond.new("B").line_for("A")
assert_equal "B B\n", Diamond.new("B").line_for("B")
assert_equal " B B \n", Diamond.new("C").line_for("B")
assert_equal "C   C\n", Diamond.new("C").line_for("C")
end
end

Diamond = Struct.new(:last) do
# [...]
def line_for(letter)
outer_padding = " " * (width - (letter.ord - FIRST.ord))
if letter == FIRST
else
inner_padding = " " * ((letter.ord - FIRST.ord) * 2 - 1)
end + "\n"
end

private

def width
last.ord - FIRST.ord
end
end


This took a few tries to get right, but seems to work. The end-to-end tests are passing now, we’re done. I wasn’t happy with this solution, though. Why? I was checking my code against Kent Beck’s four rules of simple design. Let me repeat them here:

Simple code

1. passes test, i.e. works
2. communicates intent
3. contains no duplication
4. uses a minimum amount of classes and methods

My problem was with rule 2., that the code doesn’t reflect the nature of the problem. You would never figure what the code does without running it or looking at the tests. It took me a few days to figure out another way.

## The hidden abstraction

The task of the kata is not to output a certain random string. The diamond is a geometrical shape, it’s symmetrical. In math, you would draw something like this in a two dimensional coordinate system. So if we had some kind of canvas that we can render down to a string we could express the problem in a much nicer way. Let’s try this out! Here’s a really simple (square) text canvas:

class TestCanvas < Minitest::Test
def test_draw
canvas = Canvas.new(3)
canvas[0, 0] = "X"
canvas[1, 1] = "Y"
canvas[0, 2] = "Z"
canvas[2, 0] = "A"
assert_equal <<-EOS, canvas.to_s
X A
Y
Z
EOS
end
end

Canvas = Struct.new(:size) do
def to_s
rows.map { |row| row + "\n" }.join
end

def []=(x, y, value)
rows.fetch(y)[x] = value
end

private

def rows
@rows ||= Array.new(size) { " " * size }
end
end


On this canvas we need to paint every letter four times. We don’t need a special case for the tips any more: the tips will get painted more than once, at the same position. I introduce the radius of the diamond. We need to shift everything by this value in X and Y direction as our origin 0, 0 is in the top left corner. Here’s something that works:

Diamond = Struct.new(:last) do
FIRST = "A"

def to_s
draw!
canvas.to_s
end

private

def draw!
FIRST.upto(last).zip(
).each do |letter, x, y|
end
end

def canvas
@canvas ||= Canvas.new(width)
end

end

def width
end
end


I already like this solution much better.

• We got rid of the special case.
• The symmetry of the diamond shape is reflected by the drawing operations.
• The Canvas class can be tested independently and is a component that we can easily reuse.

There’s also a thing I didn’t mention previously: we had to make Diamond#letters and Diamond#line_for public so that they could be tested. But they are really an implementation detail that no other code should depend upon. With the current implementation I’m quite happy with the feedback that the end-to-end test provides. Maybe some minor thing: the #draw! method still has some duplication, the drawing of letter looks repetitive as we always need to add the radius. According to the Four Rules of Simple Design, this is something to look out for. So let’s see if we can improve.

## More abstractions

Operations in 2D space are a well known subject. Moving around by a fixed amount is called translation. Let’s implement this as a decorator:

class TestCanvas < Minitest::Test
def test_translation
canvas = Translation.new(Canvas.new(3), 1, 1)
canvas[0, 0] = "A"
assert_equal <<-EOS, canvas.to_s

A

EOS
end
end

class Translation < SimpleDelegator
def initialize(canvas, offset_x, offset_y)
super(canvas)
@offset_x = offset_x
@offset_y = offset_y
end

def []=(x, y, value)
__getobj__[x + offset_x, y + offset_y] = value
end

private

end


The decorator logic calls for a bit of boilerplate, but the end result is nice and simple. Let’s see how we can put this to good use. Two methods in Diamond will need to change, Diamond#draw! and Diamond#canvas.

Diamond = Struct.new(:last) do
# [...]

private

def draw!
FIRST.upto(last).zip(
).each do |letter, x, y|
canvas[ x,  y] = letter
canvas[-x,  y] = letter
canvas[ x, -y] = letter
canvas[-x, -y] = letter
end
end

def canvas
@canvas ||=
Translation.new(
Canvas.new(width),
)
end


So each drawing operation got simpler at the expense of a more complicated canvas setup. We still have four drawing operations going on, though. The obvious solution is to use a loop instead like this

Diamond = Struct.new(:last) do
# [...]
def draw!
FIRST.upto(last).zip(
).each do |letter, x, y|
[[x, y], [-x, y], [x, -y], [-x, -y]].each do |coords|
canvas[*coords] = letter
end
end
end


This removes duplication but makes the #draw! method harder to read. Maybe we can solve this in a similar fashion? Let’s look at it from another angle: we’re drawing a symmetrical shape, this means that we are mirroring over the X and Y axes. So the thing we need is a reflection. This should be pretty simple to do.

class TestReflection < Minitest::Test
def test_reflection
canvas =
Reflection.new(
Translation.new(
Canvas.new(3),
1, 1
),
-1, 1
)
canvas[0, 0] = "A"
canvas[1, 1] = "B"
assert_equal <<-EOS, canvas.to_s

A
B B
EOS
end
end

class Reflection  < SimpleDelegator
def initialize(canvas, factor_x, factor_y)
super(canvas)
@factor_x = factor_x
@factor_y = factor_y
end

def []=(x, y, value)
__getobj__[x, y] = value
__getobj__[x * factor_x, y * factor_y] = value
end

private

end


This looks very similar to Translation, using multiplication instead of addition. The difference is that we’re still drawing in the original location. In order to be even more general, you could introduce a stack of canvases that get layered on top of each other during rendering. I chose not to go this route here. So what does this mean for our Diamond class?

Diamond = Struct.new(:last) do
# [...]
def draw!
FIRST.upto(last).zip(
).each do |letter, x, y|
canvas[x, y] = letter
end
end

def canvas
@canvas ||=
Reflection.new(
Reflection.new(
Translation.new(
Canvas.new(width),
),
1, -1
),
-1, 1
)
end


The setup of our canvas looks pretty complex now. Is this still simple design? Duplication is reduced, but we have more classes working together. Whether this is all worth it depends on the context. For me this is just an exercise, so I can do what I please. But what if this was happening in a business context? If the business is trying to create a terminal-based text-only drawing program for UNIX-nerds, there’s a high likelyhood that our investment in composable classes will pay off quickly. If on the other hand this task was only a one-off job to help in creating a new company logo, our efforts would have been wasteful and our first version would have been good enough.

## A parable for hidden abstractions

In hindsight the value of introducing the Canvas abstraction is obvious. Why didn’t I see it earlier? I think this is due to my upbringing as a programmer. A programmer learns how to do useful stuff with a dumb machine. We’re aware of the limits of our programming environments and take pride in how we’re still getting useful stuff done. So it’s only logical that start to think like the machine, we break the output up into individual lines and start to solve the smaller problem of creating a single line. The problem is that this is disregarding the outside context and therefore obscures the nature of the task.

This reminded me of the history of astronomy. In antiquity, astronomers were able to calculate the motion of the planets pretty accurately even though they were using the geocentric model. The Ptolemaic system was pretty complex, it assumed that planets were moving in epicycles along deferents. Similar to our first implementation, it worked just fine. But as we know today, it’s more useful to put the sun in the center. Contemporary programmers struggle with finding a better point of view just as much as the astronomers of yore.

## Abstractions and TDD

People have been saying that TDD leads to better design and I tend to agree. But TDD doesn’t write code, it doesn’t create abstractions and it doesn’t always make it obvious what next step to take. A nicely factored implementation is easy to test – it’s our job as programmers to conceive it.

## References

-1:-- Hidden abstractions in the Diamond Kata (Post admin)--L0--C0--May 07, 2017 06:56 PM

## emacspeak: Emacspeak 46.0 (HelpfulDog) Unleashed

For Immediate Release:

San Jose, Calif., (May 1, 2017)

Emacspeak 46.0 (HelpfulDog): Redefining Accessibility In The Age Of Smart Assistants
–Zero cost of Ownership makes priceless software Universally affordable!

Emacspeak Inc (NASDOG: ESPK) — http://github.com/tvraman/emacspeak — announces the
immediate world-wide availability of Emacspeak 46.0 (HelpfulDog) — a
powerful audio desktop for leveraging today's evolving data, social
and service-oriented Internet cloud.

## 1 Investors Note:

With several prominent tweeters expanding coverage of
#emacspeak, NASDOG: ESPK has now been consistently trading over
the social net at levels close to that once attained by DogCom
high-fliers—and as of May 2017 is trading at levels close to
that achieved by once better known stocks in the tech sector.

## 2 What Is It?

Emacspeak is a fully functional audio desktop that provides complete
eyes-free access to all major 32 and 64 bit operating environments. By
seamlessly blending live access to all aspects of the Internet such as
Web-surfing, blogging, social computing and electronic messaging into
information with a consistent and well-integrated user interface. A
rich suite of task-oriented tools provides efficient speech-enabled

## 3 Major Enhancements:

This version requires emacs-25.1 or later.

1. Audio-formatted Mathematics using NodeJS. ⟋🕪
1. DBus integration for handling DBus events. 🚌
2. Outloud is Easier To Install On 64-Bit Systems. ʕ
3. Managing Shell Buffers across multiple projects. 📽
4. EWW loads EBook settings when opening EPub files. 🕮
5. Bash Utils for power users. 🐚
6. Speech-Enabled Elisp-Refs. 🤞
7. Updated C/C++ Mode Support. ䷢
8. Updated EShell Support. ︹
9. Speach-Enabled Clojure. 𝍏
10. Speech-Enabled Geiser For Scheme Interaction. ♨
11. Speech-Enabled Cider. 🍎
12. Speech-Enable Racket IDE. ƛ
13. Parameterized auditory icons using SoX-Gen. 🔊
15. Speech-Enabled Projectile. 🢫
16. Spoken notifications are cached in a special buffer. ⏰
17. Flycheck And Interactive Correction. 𐄂

• And a lot more than wil fit this margin. … 🗞

## 4 Establishing Liberty, Equality And Freedom:

Never a toy system, Emacspeak is voluntarily bundled with all
major Linux distributions. Though designed to be modular,
distributors have freely chosen to bundle the fully integrated
system without any undue pressure—a documented success for
the integrated innovation embodied by Emacspeak. As the system
the same zero-cost to all users. The integrity of the Emacspeak
codebase is ensured by the reliable and secure Linux platform
used to develop and distribute the software.

Extensive studies have shown that thanks to these features, users
consider Emacspeak to be absolutely priceless. Thanks to this
wide-spread user demand, the present version remains priceless
as ever—it is being made available at the same zero-cost as
previous releases.

At the same time, Emacspeak continues to innovate in the area of
eyes-free Assistance and social interaction and carries forward the
well-established Open Source tradition of introducing user interface
features that eventually show up in luser environments.

On this theme, when once challenged by a proponent of a crash-prone
but well-marketed mousetrap with the assertion "Emacs is a system from
the 70's", the creator of Emacspeak evinced surprise at the unusual
candor manifest in the assertion that it would take popular
idiot-proven interfaces until the year 2070 to catch up to where the
Emacspeak audio desktop is today. Industry experts welcomed this
refreshing breath of Courage Certainty and Clarity (CCC) at a time
when users are reeling from the Fear Uncertainty and Doubt (FUD)
unleashed by complex software systems backed by even more convoluted
press releases.

## 5 Independent Test Results:

Independent test results have proven that unlike some modern (and
not so modern) software, Emacspeak can be safely uninstalled without
adversely affecting the continued performance of the computer. These
same tests also revealed that once uninstalled, the user stopped
functioning altogether. Speaking with Aster Labrador, the creator of
Emacspeak once pointed out that these results re-emphasize the
user-centric design of Emacspeak; "It is the user –and not the
computer– that stops functioning when Emacspeak is uninstalled!".

### 5.1 Note from Aster,Bubbles and Tilden:

UnDoctored Videos Inc. is looking for volunteers to star in a
video demonstrating such complete user failure.

## 6 Obtaining Emacspeak:

https://github.com/tvraman/emacspeak you can visit Emacspeak on the
WWW at http://emacspeak.sf.net. You can subscribe to the emacspeak
mailing list — emacspeak@cs.vassar.edu — by sending mail to the
list request address emacspeak-request@cs.vassar.edu. The Emacspeak
Blog
is a good source for news about recent enhancements and how to
use them.

The latest development snapshot of Emacspeak is always available via
Git from GitHub at
Emacspeak GitHub .

## 7 History:

• Emacspeak 46.0 (HelpfulDog) heralds the coming of Smart Assistants.
• Emacspeak 45.0 (IdealDog) is named in recognition of Emacs'
excellent integration with various programming language
environments — thanks to this, Emacspeak is the IDE of choice
for eyes-free software engineering.
• Emacspeak 44.0 continues the steady pace of innovation on the
audio desktop.
• Emacspeak 43.0 brings even more end-user efficiency by leveraging the
ability to spatially place multiple audio streams to provide timely
auditory feedback.
• Emacspeak 42.0 while moving to GitHub from Google Code continues to
innovate in the areas of auditory user interfaces and efficient,
light-weight Internet access.
• Emacspeak 41.0 continues to improve
on the desire to provide not just equal, but superior access —
technology when correctly implemented can significantly enhance the
human ability.
• Emacspeak 40.0 goes back to Web basics by enabling
• Emacspeak 39.0 continues the Emacspeak tradition of increasing the breadth of
user tasks that are covered without introducing unnecessary
bloatware.
• Emacspeak 38.0 is the latest in a series of award-winning
releases from Emacspeak Inc.
• Emacspeak 37.0 continues the tradition of
delivering robust software as reflected by its code-name.
• Emacspeak 36.0 enhances the audio desktop with many new tools including full
EPub support — hence the name EPubDog.
• Emacspeak 35.0 is all about
teaching a new dog old tricks — and is aptly code-named HeadDog in
on of our new Press/Analyst contact. emacspeak-34.0 (AKA Bubbles)
an eyes-free environment.
• Emacspeak-33.0 AKA StarDog brings
• Emacspeak 32.0 AKA
LuckyDog continues to innovate via open technologies for better
access.
• Emacspeak 31.0 AKA TweetDog — adds tweeting to the Emacspeak
desktop.
• Emacspeak 30.0 AKA SocialDog brings the Social Web to the
audio desktop—you cant but be social if you speak!
• Emacspeak 29.0—AKAAbleDog—is a testament to the resilliance and innovation
embodied by Open Source software—it would not exist without the
thriving Emacs community that continues to ensure that Emacs remains
one of the premier user environments despite perhaps also being one of
the oldest.
• Emacspeak 28.0—AKA PuppyDog—exemplifies the rapid pace of
development evinced by Open Source software.
• Emacspeak 27.0—AKA
FastDog—is the latest in a sequence of upgrades that make previous
• Emacspeak 26—AKA
solutions that are unfettered by the constraints inherent in
• Emacspeak 25 —AKA ActiveDog
information.
• Emacspeak-Alive —AKA LiveDog —enlivens open, unfettered
information access with a series of live updates that once again
demonstrate the power and agility of open source software
development.
• Emacspeak 23.0 — AKA Retriever—went the extra mile in
fetching full access.
• Emacspeak 22.0 —AKA GuideDog —helps users
navigate the Web more effectively than ever before.
• Emacspeak 21.0
—AKA PlayDog —continued the
Emacspeak tradition of relying on enhanced
productivity to liberate users.
• Emacspeak-20.0 —AKA LeapDog —continues
the long established GNU/Emacs tradition of integrated innovation to
create a pleasurable computing environment for eyes-free
interaction.
• emacspeak-19.0 –AKA WorkDog– is designed to enhance
user productivity at work and leisure.
• Emacspeak-18.0 –code named
GoodDog– continued the Emacspeak tradition of enhancing user
productivity and thereby reducing total cost of
ownership.
• Emacspeak-17.0 –code named HappyDog– enhances user
productivity by exploiting today's evolving WWW
standards.
• Emacspeak-16.0 –code named CleverDog– the follow-up to
SmartDog– continued the tradition of working better, faster,
smarter.
• Emacspeak-15.0 –code named SmartDog–followed up on TopDog
as the next in a continuing series of award-winning audio desktop
releases from Emacspeak Inc.
• Emacspeak-14.0 –code named TopDog–was

the first release of this millennium.

• Emacspeak-13.0 –codenamed
YellowLab– was the closing release of the
20th. century.
• Emacspeak-12.0 –code named GoldenDog– began
leveraging the evolving semantic WWW to provide task-oriented speech
• Emacspeak-11.0 –code named Aster– went the
final step in making Linux a zero-cost Internet access solution for
blind and visually impaired users.
• Emacspeak-10.0 –(AKA
Emacspeak-2000) code named WonderDog– continued the tradition of
award-winning software releases designed to make eyes-free computing a
productive and pleasurable experience.
• Emacspeak-9.0 –(AKA
Emacspeak 99) code named BlackLab– continued to innovate in the areas
of speech interaction and interactive accessibility.
• Emacspeak-8.0 –(AKA Emacspeak-98++) code named BlackDog– was a major upgrade to
the speech output extension to Emacs.
• Emacspeak-95 (code named Illinois) was released as OpenSource on
the Internet in May 1995 as the first complete speech interface
to UNIX workstations. The subsequent release, Emacspeak-96 (code
named Egypt) made available in May 1996 provided significant
enhancements to the interface. Emacspeak-97 (Tennessee) went
further in providing a true audio desktop. Emacspeak-98
integrated Internetworking into all aspects of the audio desktop
to provide the first fully interactive speech-enabled WebTop.

Originally based at Cornell (NY) —
http://www.cs.cornell.edu/home/raman —home to Auditory User
Interfaces (AUI) on the WWW, Emacspeak is now maintained on GitHub
https://github.com/tvraman/emacspeak. The system is mirrored
world-wide by an international network of software archives and
bundled voluntarily with all major Linux distributions. On Monday,
April 12, 1999, Emacspeak became part of the Smithsonian's Permanent
Research Collection
on Information Technology at the Smithsonian's
National Museum of American History.

The Emacspeak mailing list is archived at Vassar –the home of the
Emacspeak mailing list– thanks to Greg Priest-Dorman, and provides a
valuable knowledge base for new users.

## 9 Press/Analyst Contact: Tilden Labrador

Going forward, Tilden acknowledges his exclusive monopoly on
setting the direction of the Emacspeak Audio Desktop, and
promises to exercise this freedom to innovate and her resulting
power responsibly (as before) in the interest of all dogs.

Windows-Free (WF) is a favorite battle-cry of The League Against
Forced Fenestration (LAFF). –see
http://www.usdoj.gov/atr/cases/f3800/msjudgex.htm for details on
the ill-effects of Forced Fenestration.

CopyWrite )C( Aster, Hubbell and Tilden Labrador. All Writes Reserved.
HeadDog (DM), LiveDog (DM), GoldenDog (DM), BlackDog (DM) etc., are Registered
Dogmarks of Aster, Hubbell and Tilden Labrador. All other dogs belong to
their respective owners.

-1:-- Emacspeak 46.0 (HelpfulDog) Unleashed (Post T. V. Raman (noreply@blogger.com))--L0--C0--April 30, 2017 03:12 PM

## Manuel Uberti: Daily Clojure workflow

It’s already been a month since I started my new job. All is going well and just as expected, and it’s been interesting to see how my carefully tuned Emacs configuration dealt with everyday Clojure programming.

Truth be told, I’ve never used Emacs consistently for work. Before Clojure I mainly did Java and Emacs support for Java is not as good as what it offers for other programming languages. Yes, I kept Emacs around for other stuff, but it would be a dull lie to tell I was proudly using Emacs all day in the office.

Anyway, Clojure is the new kid in town now so it’s Emacs all the way. The obvious first choice is CIDER and I genuinely don’t have enough words to say how wonderful it is. I couple it with clj-refactor and Smartparens to get the most out of my coding experience.

I especially love how CIDER enables me to switch easily between Clojure and ClojureScript, with two REPLs ready to go and documentation just under my fingertips. clj-refactor enriches exploratory development with hot reloading of dependencies and handy change of missing requires.

Then there is Projectile. Even on small Clojure projects we are using to test available libraries there are plenty of files around. Mickey Petersen talks about tempo when it comes to using Emacs. Projectile guarantees you don’t lose your tempo while working on projects of different sizes.

What else? I don’t think Magit needs my over enthusiastic words. Ivy is proving to be the right tool at the right time, with Swiper ever so helpful. And now I am only waiting for the day we will need proper documents to bring out the almighty AUCTeX.

In the immortal words of Bozhidar Batsov:

Emacs is power.

Emacs is magic.

Emacs is fun.

Emacs is forever.

-1:-- Daily Clojure workflow (Post)--L0--C0--April 29, 2017 12:00 AM

# Email On The Emacspeak Audio Desktop

## 1 Overview

This question comes up every few months on the emacspeak mailing
list. In general, see
Emacspeak Tools to quickly discover available speech-enabled
given the wide degree of variance in this space.

## 2 Background

How one puts together an email environment is a function of the
following:

1. How email is retrieved.
2. How email is stored (if storing locally).
3. How email is sent.

Here is an overview of what is available as viewed from the world of
Linux in general and Emacs in particular:

### 2.1 Email Retrieval

Email can be retrieved in a number of ways:

• IMap via Emacs This is implemented well in GNUS, and poorly in
Emacs/VM. Note that Emacs is single-threaded, and fetching large
volumes of email via IMap is painful.
• Batch Retrieval: IMap Tools like fetchmail, offlineimap and friends that live
outside of Emacs can be used to batch-retrieve email in the
background. The retrieved mail gets delivered locally as in the past.
• Mail Filtering: UNIX procmail enables filtering of locally
delivered email into separate folders for automatically organizing
incoming email.

### 2.2 Sending Email

Sending email involves:

1. Composing email — typically invoked via key-sequence C-x m
(command: compose-mail). Emacs email packages implement
specific versions of this command, e.g. vm-mail from package
emacs/vm, message-mail from the message package etc.
2. Sending email: This is specific to the email provider being used,
e.g., GMail. In the past, UNIX machines could talk SMTP to
the Mail Gateway, but this has mostly disappeared over time. For
an example of how to configure Emacs to send email via GMail
using SMTP , see file tvr/gm-smtp.el in the emacspeak repository.

### 2.3 Local Storage Format

• UNIX Mail: An email folder is a file of messages. This
format is used by clients like Emacs/VM, UNIX Mail etc.
• Maildir: A mail folder is a directory, with
individual email messages living in files of their
own. Sample clients include MH-E (UNIX MH), MU4E.
• RMail This is Emacs' original email format.

## 3 Putting It All Together

The next sections show my present email setup put together using the
building blocks described above.

1. I use Linux on all my machines, and Android on my phone.
2. I mostly limit email usage on my phone to get a quick overview of email that might require immediate attention — toward this end, I have a to-mobile GMail label that collects urgent messages.
3. Linux is where I handle email in volume.
4. I use my Inbox as

my ToDo list — which means that I leave little or no email in my
Inbox unless I'm on vacation and disconnected from email.

### 3.1 Desktop: Batch Retrieval And Emacs/VM

This is the email setup on my workstation. See next section for the
email setup while mobile.

1. I batch-retrieve email using fetchmail.
2. This email gets filtered through procmail and auto-filed into
several folders based on a set of procmail rules. Typical rules
include separating out various email lists into their respective folders.
3. Note that this does not preclude using IMap via GNUS to read
email while online.
4. Email that is not filtered into separate folders e.g. email that
is sent directly to me, email regarding projects that need
immediate attention etc., land up in folder ~/mbox.
5. So when I launch emacs/vm on my desktop, the above is all I
need to deal with at any given moment.
6. I typically read Auto-filed mailing lists using emacs/vm about once a day or
less — I use package mspools to get a quick overview of the
state of those mail folders.

### 3.2 Mobile AccessOn Laptop: GNUS And IMap

See gnus-prepare.el for my gnus configuration for accessing GMail
via imap. That configuration is setup to access multiple GMail accounts.

1. I see each GMail label as a separate group in GNUS.
2. I only sync high-priority labels — this works well even
over slow WIFI connections while on the road. As an example, the
afore-mentioned to-mobile GMail label is a high-priority group.
3. Module gm-nnir defines a GNUS/GMail extension that enables
one to search GMail using GMail's search operators — that is my
prefered means of quickly finding email messages using
search. This is very fast since the search happens server-side,
and only email headers are retrieved when displaying the search
hits.
4. Note that this solution is not laptop/mobile specific — I use
this setup for searching GMail from my desktop as well.

### 3.3 Composing And Sending EMail

1. I use compose-mail to compose email.
2. I optionally activate orgtbl-mode and/or orgstruct-mode if
editing structured content within the email body.
3. I send email out using the setup in gm-smtp.el.

## 4 Conclusion

1. Email in Linux/Emacs is composed of a set of
independent building blocks — this gives maximal flexibility.
2. That flexibility allows one to put together different email
workflows depending on the connectivity environment in use.
-1:-- Mail On The emacspeak Audio Desktop (Post T. V. Raman (noreply@blogger.com))--L0--C0--April 23, 2017 03:19 AM

## Got Emacs?: Emacs 25.2 Released

The bug fix version of Emacs 25.2 is released.  More information can be seen in the official announcement
-1:-- Emacs 25.2 Released (Post sivaram (noreply@blogger.com))--L0--C0--April 21, 2017 04:31 PM`