Irreal: Helpful

I haven’t paid too much attention to Wilfred Hughes’ Helpful but judging from Hughes’ latest tweet:

that may have been a mistake.

Is anyone here using it? If so, do you recommend it as a worthy addition to one’s set of packages?

-1:-- Helpful (Post jcs)--L0--C0--December 12, 2017 06:06 PM

Marcin Borkowski: Funny places in fill.el

Some time ago, I read parts of fill.el. This turned out to be rather a rewarding experience, in a rather warped sense. Let me quote a few highlights from that file.
-1:-- Funny places in fill.el (Post)--L0--C0--December 11, 2017 09:14 PM

sachachua: 2017-12-11 Emacs news

Links from, /r/orgmode, /r/spacemacs, Hacker News,, YouTube, the changes to the Emacs NEWS file, and emacs-devel.

-1:-- 2017-12-11 Emacs news (Post Sacha Chua)--L0--C0--December 11, 2017 09:24 AM

(or emacs: Comparison of transaction fees on Patreon and similar services

On December 7, Patreon made an announcement about the change in their transaction fee structure. The results as of December 10 speak for themselves:

December 2017 summary: -$29 in pledges, -6 patrons

All leaving patrons marked "I'm not happy with Patreon's features or services." as the reason for leaving, with quotes ranging from:

The billing changes are not great.


Patreon's new fees are unacceptable

In this article, I will explore the currently available methods for supporting sustainable Free Software development and compare their transaction fees.

My experience

My experience taking donations is very short. I announced my fund raising campaign on Patreon in October 2017.

Here's what I collected so far, vs the actual money spent by the contributors:

  • 2017-11-01: $140.42 / $162.50 = 86.41%
  • 2017-12-01: $163.05 / $187.50 = 86.96%

The numbers here are using the old Patreon rules that are going away this month.

Real numbers

method formula charged donated fee
old Patreon ??? $1.00 $0.86 14%
new Patreon 7.9% + $0.35 $1.38 $0.95 31%
    $2.41 $1.90 21%
    $5.50 $4.75 14%
OpenCollective 12.9% + $0.30 $1.33 $0.90 32%
    $2.36 $1.80 24%
    $5.45 $4.50 18%
Flattr 16.5% $1.00 $0.84 17%
    $2.00 $1.67 17%
    $5.00 $4.18 17%
Liberapay 0.585% $1.00 $0.99 1%

On Patreon

Just like everyone else, I'm not happy with the incoming change to the Patreon fees. But even after the change, it's still a better deal than OpenCollective, which is used quite successfully e.g. by CIDER.

Just to restate the numbers in the table, if all backers give $1 (which is the majority currently, and I actually would generally prefer 5 new $1 backers over 1 new $5 backer), with the old system I get $0.86, while with the new system it's $0.69. That's more than 100% increase in transaction fees.

On OpenCollective

It's more expensive than the new Patreon fees in every category or scenario.

On Flattr

Flattr is in the same bucket as Patreon, except with slightly lower fees currently. Their default plan sounds absolutely ridiculous to me: you install a browser plug-in so that a for-profit corporation can track which websites you visit most often in order to distribute the payments you give them among those websites.

If it were a completely local tool which doesn't upload any data on the internet and instead gives you a monthly report to adjust your donations, it would have been a good enough tool. Maybe with some adjustments for mind-share bubbles, which result in prominent projects getting more rewards than they can handle, while small projects fade away into obscurity without getting a chance. But right now it's completely crazy. Still, if you don't install the plug-in, you can probably still use Flattr and it will work similarly to Patreon.

I made an account, just in case, but I wouldn't recommend going to Flattr unless you're already there, or the first impression it made on me is wrong.

On Paypal

Paypal is OK in a way, since a lot of the time the organizations like Patreon are just middle men on top of Paypal. On the other hand, there's no way to set up recurring donations. And it's harder for me to plan decisions regarding my livelihood if I don't know at least approximately the sum I'll be getting next month.

My account, in case you want to make a lump sum donation:

On Bitcoin

Bitcoin is similar to Paypal, except it also:

  • has a very bad impact on the environment,
  • is a speculative bubble that supports either earning or losing money without actually providing value to the society.

I prefer to stay away from Bitcoin.


Liberapay sounds almost too good to be true. At the same time, their fees are very realistic, you could almost say optimal, since there are no fees for transfers between members. So you can spend either €20.64 (via card) or €20.12 (via bank wire) to charge €20 into your account and give me €1 per month at no further cost. If you change your mind after one month, you can withdraw your remaining €19 for free if you use a SEPA (Single Euro Payments Area) bank.

If I set out today to set up a service similar to Liberapay, even with my best intentions and the most optimistic expectations, I don't see how a better offer could be made. I recommend anyone who wants to support me to try it out. And, of course, I will report back with real numbers if anything comes out of it.

Thanks to all my patrons for their former and ongoing support. At one point we were at 30% of the monthly goal (25% atm.). This made me very excited and optimistic about the future. Although I'm doing Free Software for almost 5 years now, it's actually 3 years in academia and 2 years in industry. Right now, I'm feeling a burnout looming over the horizon, and I was really hoping to avoid it by spending less time working at for-profit corporations. Any help, either monetary or advice is appreciated. If you're a part of a Software Engineering or a Research collective that makes you feel inspired instead of exhausted in the evening and you have open positions in EU or on remote, have a look at my LinkedIn - maybe we could become colleagues in the future. I'll accept connections from anyone - if you're reading this blog, we probably have a lot in common; and it's always better together.

-1:-- Comparison of transaction fees on Patreon and similar services (Post)--L0--C0--December 09, 2017 11:00 PM

Irreal: End Your List Items with a Period

Grant Rettke over at Wisdom and Wonder has helped me resolve a long standing conundrum. When I have a list

  • like
  • this

I can never decide whether or not to end each list item with a period. I can adduce compelling arguments for both choices so I’m always conflicted. Rettke says to always end a list item with a period. The reason, he says, is so that text-to-speech software will pause at the end of each list item rather than running them on.

I never use text-to-speech but I’m willing to concede that someone else reading my writing might want to for various reasons so my new rule is to end the list items with a period. Thanks for clearing that up, Grant.

-1:-- End Your List Items with a Period (Post jcs)--L0--C0--December 09, 2017 07:05 PM

Manuel Uberti: Learning Haskell

Since my first baby steps in the world of Functional Programming, Haskell has been there. Like the enchanting music of a Siren, it has been luring me with promises of a new set of skills and a better understanding of the lambda calculus.

I refused to oblige at first. A bit of Scheme and my eventual move to Clojure occupied my mind and my daily activities. Truth be told, the odious warfare between dynamic types troopers and static types zealots didn’t help steering my enthusiasm towards Haskell.

Still, my curiosity is stoic and hard to kill and the Haskell Siren was becoming too tempting to resist any further. The Pragmatic Programmer in me knew it was the right thing to do. My knowledge portfolio is always reaching out for something new.

My journey began with the much praised Programming in Haskell. I kept track of the exercises only to soon discover this wasn’t the right book for me. A bit too terse and schematic, I needed something that could ease me in in a different way. I needed more focus on the basics, the roots of the language.

As I usually do, I sought help online. I don’t know many Haskell developers, but I know there are crazy guys in the Emacs community. Steve Purcell was kind and patient enough to introduce me to Haskell Programming From First Principles.

This is a huge book (nearly 1300 pages), but it just took the authors’ prefaces to hook me. Julie Moronuki words in particular resonated heavily with me. Unlike Julie I have experience in programming, but I felt exactly like her when it comes to approaching Haskell teaching materials.

So here I am, armed with Stack and Intero and ready to abandon myself to the depths and wonders of static typing and pure functional programming. I will track my progress and maybe report back here. I already have a project in mind, but my Haskell needs to get really good before starting any serious work.

May the lambda be with me.

-1:-- Learning Haskell (Post)--L0--C0--December 08, 2017 12:00 AM

Alex Schroeder: Emacs on Windows

Getting M-x eww to work:

  1. get from
  2. put the dll files from the bin subdirectory into the Emacs bin subdirectory
  3. add the Emacs bin directory to your PATH environment variable

That’s what they say. But it doesn’t work.

The Emacs Wiki agrees.

Suspiciously, the names differ: libiconv-2.dll, libxml2-2.dll, and zlib1.dll.


-1:-- Emacs on Windows (Post)--L0--C0--December 06, 2017 01:35 PM

sachachua: External brains – current state

Being the primary caregiver for a toddler means I’m distracted, often interrupted, and somewhat sleep-deprived, so using external brains (paper, phone, laptop) helps a lot. Here are a few things I rely on them to keep so that I can declutter my mind, worry less, and be more present:

  • Daily journal: This lets me tell W- stories about A-, appreciate A-‘s progress, and feel good about where the time went. I use Memento Database on my Android phone to add datestamped, categorized text notes to a Google Sheets spreadsheet.
  • Weekly/monthly review: This lets me appreciate progress over a longer period and plan for the next one. I edit the daily journal entries in Memento to set their importance (1: weekly highlight, 2: monthly), then filter, sort, group, and export the entries. I copy the text into Tasks Free (which synchronizes via Google Tasks) and then edit the text on my phone while A- nurses and sleeps. If I manage to have computer time, I might use Emacs to fill in more of my weekly or monthly review.
  • Tasks (next actions, inbox, waiting, thoughts, and assorted other lists): Tasks Free on my phone, since I can check it or add to it any time. I jot ideas/thoughts down here too, since I can write while nursing A- in bed. If I run out of battery, I charge my phone and move to W-‘s old phone, so I can keep writing. After I draft a thought that might be a good blog post, I copy it into the WordPress app and post it so that I can find it again later. (And so that other people might chime in with insights!) If I have time, I might copy a thought into Emacs, flesh it out further, and post it with org2blog.
  • Calendar: Google calendars – one for appointments, one for activity options. This way, I can hide all the optional stuff quickly.
  • Longer-term reminders, notes, work in progress: Org files. It’s so nice to be able to schedule tasks and have detailed notes on how to complete those tasks. I also really like being able to break things down with outlines and think out loud with code snippets. The weekly agenda review helps me catch reminders.
  • Photos and videos: I sync a Wi-Fi-enabled camera with my phone, then erase everything off the camera. Google Photos automatically uploads everything and shares them with W-. I post selected things to a Facebook closed group for kiddo updates.
  • Time and activity log: I track my time for curiosity. I made my own tracker (, and I made another button-based interface for easier tracking on my phone. That interface also lets me quickly log data to, where I track A-‘s sleep, nursing, and potty use. I made my own visualizations, too.
  • Reference info: Org. Document scans in Dropbox or Owncloud, some GPG-encrypted.
  • Book notes: I’ve been reading mostly e-books from the library, so I take screenshots on my phone and they go through my photo workflow. I use Tasks Free to capture quick notes about paper books. I’d like to get back to sketchnotes when I have more focused time.
  • New words: I’m tracking this out of curiosity. She has said 350+ different words, and she’s not even 2 years old yet. :) Many of the words come from songs and books, so it helps to think of concrete experiences she can associate them with.
  • Scenarios, just-in-case notes: Org. Good for managing risks and worrying less.
  • Processes: Org. Good for step-by-step instructions when I’m sleep-deprived or doing something infrequently.
  • Finances: Ledger-cli. Text-based accounting, yay! I have some reports in ledger-mode and some in an Org file. I update this monthly or so.
  • Cooking: We manage our grocery list in OurGroceries because of the multiuser real-time sync. Recipes tend to be looked up on the Internet and then copied into a paper notebook or onto an index card when we like them. Meal plan is written on scrap paper and stuck to the front of the fridge.

I want to get better at structuring my observations of A-‘s progress, planning follow-up activities, and keeping the overall picture in mind. Since I’m roughly categorizing the daily journal entries in Memento / Google Sheets, I can probably create a table that will make it easy to see if there are neglected areas, and then extend that to plan ideas. Or, well, as much planning as one can do with a toddler, really – more like keeping an eye out for opportunities to build on A-‘s interests. So far it’s been okay, though. I’ve been learning about basic principles and skill components from textbooks on early childhood education, and that makes it a bit easier for me to improvise. I have a rough outline of areas to think about on a regular basis, and a few ideas to explore over the next few months.

I also want to get better at managing my book notes and other ideas I want to revisit at the appropriate time. I’m a little lacking on the review side, since most of my writing time is taken up by capturing observations and the occasional reflection. So far, this has also been okay. I just have to trust that whatever I’m writing down will still make sense to me in a few months or years, and the most important stuff will turn up on my radar at the appropriate time. Schedule-based reminders are easy, but things wait for all sorts of other factors. For example, there are lots of practical life skill exercises I picked up from the Montessori education books that will be a better fit when A-‘s fine motor skills improve.

I’d like to get back to drawing someday, although it may have to wait until I have more dedicated time. Whenever I start sketching out a thought, A- likes drawing on my paper or asking me to draw stuff for her. It’s all good, though, since it encourages us to scribble. It just means that I can’t take a picture and reuse the drawing – I have to type it up anyway, so I may as well explore the thought on my phone unless I want to think nonlinearly.

I’ll experiment with using timestamped notes in Memento to help me with offline logging when we go on our trip. I might also just spring for Internet access once we’re off the plane, since that’s useful for other things as well.

I’ve got a fair bit of clutter in my Org files, but I trust that the outlining tools will help me reorganize as needed. I tend to do just-in-time organizing: instead of starting with an outline and drilling down, I might capture a bunch of thoughts, refile them as the structure becomes clearer, and then work up and down from there.

I don’t spend nearly as much time on the computer as I might want to for optimal external-brain management, but the current system is surprisingly workable. Shifting more of my writing to my phone (including the weekly/monthly summaries) made a difference, since I don’t have to keep as much in my head or get constrained by computer time. I look forward to tweaking how things work as A- becomes more independent and as I learn more.

-1:-- External brains – current state (Post Sacha Chua)--L0--C0--December 05, 2017 10:25 AM

Marcin Borkowski: Embedding files in Org-mode

A few days ago, there was a question on the help-gnu-emacs mailing list about a way to embed an image in a text file. Of course, the OP was instantly pointed to Org-mode. However, this does not quite do what he wanted: while you can have attachments/links to images in Org, you then need two files instead of one. This being Emacs and Org-mode, there exists an (at least partial) solution.
-1:-- Embedding files in Org-mode (Post)--L0--C0--December 04, 2017 09:59 AM

Sanel Zukan: Distraction-free EWW surfing

Sometimes when I plan to read a longish html text, I fire up EWW, a small web browser that comes with Emacs.

However, reading pages on larger monitor doesn't provide good experience, at least not for me. Here is an example:


Let's fix that with some elisp code:

(defun eww-more-readable ()
  "Makes eww more pleasant to use. Run it after eww buffer is loaded."
  (setq eww-header-line-format nil)               ;; removes page title
  (setq mode-line-format nil)                     ;; removes mode-line
  (set-window-margins (get-buffer-window) 20 20)  ;; increases size of margins
  (redraw-display)                                ;; apply mode-line changes
  (eww-reload 'local))                            ;; apply eww-header changes

EWW already comes with eww-readable function, so I named it eww-more-readable.

Evaluate it and call with:

M-x eww-more-readable

Result is much better now:


EDIT: Chunyang Xu noticed that elisp code had balanced parentheses issue and also suggested to use (eww-reload 'local) to avoid re-fetching the page. Thanks!

-1:-- Distraction-free EWW surfing (Post)--L0--C0--November 30, 2017 11:00 PM

Pragmatic Emacs: Reorder TODO items in your org-mode agenda

I use org-mode to manage my to-do list with priorities and deadlines but inevitably I have multiple items without a specific deadline or scheduled date and that have the same priority. These appear in my agenda in the order in which they were added to my to-do list, but I’ll sometimes want to change that order. This can be done temporarily using M-UP or M-DOWN in the agenda view, but these changes are lost when the agenda is refreshed.

I came up with a two-part solution to this. The main part is a generic function to move the subtree at the current point to be the top item of all subtrees of the same level. Here is the function:

(defun bjm/org-headline-to-top ()
  "Move the current org headline to the top of its section"
  ;; check if we are at the top level
  (let ((lvl (org-current-level)))
     ;; above all headlines so nothing to do
     ((not lvl)
      (message "No headline to move"))
     ((= lvl 1)
      ;; if at top level move current tree to go above first headline
      ;; test if point is now at the first headline and if not then
      ;; move to the first headline
      (unless (looking-at-p "*")
        (org-next-visible-heading 1))
     ((> lvl 1)
      ;; if not at top level then get position of headline level above
      ;; current section and refile to that position. Inspired by
      (let* ((org-reverse-note-order t)
             (pos (save-excursion
                    (outline-up-heading 1)
             (filename (buffer-file-name))
             (rfloc (list nil filename nil pos)))
        (org-refile nil nil rfloc))))))

This will move any to-do item to the top of all of the items at the same level as that item. This is equivalent to putting the cursor on the headline you want to move and hitting M-UP until you reach the top of the section.

Now I want to be able to run this from the agenda-view, which is accomplished with the following function, which I then bind to the key 1 in the agenda view.

(defun bjm/org-agenda-item-to-top ()
    "Move the current agenda item to the top of the subtree in its file"
  ;; save buffers to preserve agenda
  ;; switch to buffer for current agenda item
  ;; move item to top
  ;; go back to agenda view
  (switch-to-buffer (other-buffer (current-buffer) 1))
  ;; refresh agenda

  ;; bind to key 1
  (define-key org-agenda-mode-map (kbd "1") 'bjm/org-agenda-item-to-top)

Now in my agenda view, I just hit 1 on a particular item and it is moved permanently to the top of its level (with deadlines and priorities still taking precedence in the final sorting order).

-1:-- Reorder TODO items in your org-mode agenda (Post Ben Maughan)--L0--C0--November 30, 2017 09:56 PM

Emacs café: Introducing Elbank

Elbank is a new Emacs package I’ve been working on lately. It’s a personal finances and budgeting package for Emacs that uses Weboob for scraping data from bank websites.

Overview buffer

I started building Elbank after using Ledger for several years. While Ledger is a real gem, I didn’t want to spend time doing bookkeeping anymore.

Instead, I wanted a simple reporting tool that would automatically scrap data and build reports within Emacs from it.

Setting up Weboob

To use Elbank, you will first have to install Weboob. Weboob is a collection of applications used to interact with websites from the command-line. Elbank uses the banking application named boobank to scrap data.

The list of currently supported bank websites is available on this page.

Fortunately, installing Weboob should be a breeze as there are packages for most GNU/Linux distros, and an homebrew formula for Mac users.

Once Weboob is installed, run boobank in a console to setup your accounts.

Installing Elbank

You can now install elbank from MELPA1 by running M-x package-install RET elbank RET, and voila!

Using Elbank

The overview buffer

Run M-x elbank-overview to get started. The overview buffer lists all accounts as custom reports and budgets.

Press u to import the bank statements from your bank website.

You can click on each account or report displayed in the buffer to open them.

Categorizing transactions

Transaction categories is an important aspect of Elbank. Categories make it possible to filter and budget.

Transactions are automatically categorized when reporting, using the custom variable elbank-categories.

Here’s an example value for elbank-categories, you should adjust it based on your own transactions and categorizing needs.

(setq elbank-categories
      '(("Expenses:Food" . ("^supermarket" 
                            "Local store XXX" 
                            "Bakery XXX"))
        ("Expenses:Rent" . ("Real Estate Agency XXX"))
        ("Income:Salary" . ("Bank transfer from Company XXX"))))

Each transaction’s text is matched against the regular expressions of elbank-categories, the first match defines the category of a transaction.


Evaluate M-x elbank-report to create a new report. The command will ask you for an account, period and category, which are all optional.


Here’s the list of keybindings available in a report buffer:

  • f c: Filter the transactions by category
  • f a: Only show transactions in a specified account
  • f p: Select the period of the report
  • G: Group transactions by some property
  • S: Sort transactions
  • s: Reverse the sort order
  • M-p: Move backward by one period (month or year)
  • M-n: Move forward by one period (month or year)

You can also customize the variable elbank-saved-monthly-reports and elbank-saved-yearly-reports to conveniently get a quick list of commonly used reports from the overview buffer.


The custom variable elbank-budget is used to define a monthy budget. It defines how much money we want to spend by category of transaction, like "Food" or "Rent".

(setq elbank-budget '(("Expenses:Food" . 300)
                      ("Expenses:Rent" . 450)
                      ("Expenses:Transport" . 120)
                      ("Expenses:Utilities" . 145)))

Note that budgeted amounts are positive numbers while expenses have negative values.

Press b from the overview buffer or evaluate M-x elbank-budget-report to see your expenses based on your budget.

Budget report

You can switch periods with M-p and M-n the same way as in report buffers.


That’s all for now!

Elbank is still in its infancy, but I’m already using it daily. If you find any bug or would like to suggest improvements, feel free to open a ticket on the GitHub project.

  1. As of today, the package is not yet in MELPA, but a pull request is in review to add it to the repository. 

-1:-- Introducing Elbank (Post Nicolas Petton)--L0--C0--November 30, 2017 01:28 PM

(or emacs: Ivy 0.10.0 is out


Ivy is a completion method that's similar to Ido, but with emphasis on simplicity and customizability.


The current release constitutes of 280 commits and 8 months of progress since 0.9.0. Many issues ranging from #952 to #1336 were fixed. The number of people who contributed code as grown to 91; thanks, everyone!

Details on changes has been a part of the repository since 0.6.0, you can get the details of the current and past changes:


Many improvements are incremental and don't require any extra code to enable. I'll go over a few selected features that require a bit of information to make a good use of them.

Selectable prompt

Off by default. You can turn it on like so:

(setq ivy-use-selectable-prompt t)

After this, your current input becomes selectable as a candidate. Press C-p when you're on the first candidate to select your input instead.

This solves the long standing issue of e.g. creating a file or a directory foo when a file foobar already exists. Previously, the only solution was to use C-M-j. It's still available, but now you can also select your input with C-p and press RET.

New global actions for ivy

ivy-set-actions was used to enable the following bindings:

  • Press M-o w to copy the current candidate to the kill ring.
  • Press M-o i to insert the current candidate into the buffer.

These bindings are valid for any completion session by default.

Use C-d in ivy-occur buffers

Here's an example use-case: search your source code for a variable name with e.g. counsel-rg and call ivy-occur (C-c C-o). Suppose you get 10 results, only 4 of which are interesting. You can now delete the uninteresting ones with C-d. Then maybe check off the others with C-d as well as you complete them one by one. A sort of a TODO list.

Similarly, if you want to go over variables to customize, you can call counsel-describe-variable with input ^counsel-[^-] and then check off the ones you have already examined with C-d.

Defcustoms to play with

Here's the list of new defcustom or defvar that might be interesting to review:

  • counsel-async-filter-update-time
  • counsel-async-ignore-re
  • counsel-describe-function-function
  • counsel-describe-function-preselect
  • counsel-find-file-ignore-regexp
  • counsel-fzf-dir-function
  • counsel-git-grep-skip-counting-lines
  • counsel-git-log-split-string-re
  • counsel-url-expansions
  • ivy-auto-select-single-candidate
  • ivy-magic-slash-non-match-action
  • ivy--preferred-re-builders
  • ivy-truncate-lines

New Commands

14 new commands were added by me and many contributors. Here's the list:

  • counsel-ack - completion for ack
  • counsel-apropos - completion for apropos
  • counsel-file-register - completion for file registers
  • counsel-fzf - completion for fzf
  • counsel-git-change-worktree - completion for git-worktree
  • counsel-git-checkout - completion for git-checkout
  • counsel-minibuffer-history - generalization of counsel-expression-history and counsel-shell-command-history
  • counsel-org-capture - completion for org-capture
  • counsel-org-file - browse all attachments for the current Org file
  • counsel-org-goto - completion for Org headings
  • counsel-org-goto-all - completion for Org headings in all open buffers
  • counsel-switch-to-shell-buffer - switch to a shell buffer, or create one
  • ivy-occur-delete-candidate - delete current candidate in ivy-occur-mode
  • ivy-switch-view - select a window configuration, decoupled from ivy-switch-buffer

My personal favorites are counsel-fzf and counsel-org-file.


Again, thanks to all the contributors. Happy hacking!

P.S. Please consider joining my 74 patrons to give me the opportunity to work on Free Software a lot more. We are currently at 30% of the goal.

-1:-- Ivy 0.10.0 is out (Post)--L0--C0--November 29, 2017 11:00 PM

Manuel Uberti: boodle

The usefulness of in-house accounting has become evident only in recent years. On different occasions, my wife and I discussed a solution for keeping track of expenses and available budget for short- and long-term goals. Simply put: the bank statement was not enough any more.

In the past we relied on ledger, knowing too well the power of plain text. For a while we succeeded in our money management, because ledger is really that good. However, soon we started thinking about savings and goals, about a custom user interface to have a better understanding of our financial situation.

Naturally, I decided to use some of the experience I gained at work to develop our own application. I wanted a simple single-page application that would enable us to:

  • track expenses
  • query expenses to get reports
  • track short- and long-term goals

boodle (a synonym of money, in case you are wondering) has the following architecture:

I have set up bidi for client-side routing, compojure for server-side routing and compojure-api to connect client and server via pleasant APIs.

Thanks to mount I have three main components that I can start and stop to make development and debugging easier: application configuration, database and HTTP server.

I decided to give dire a try, appreciating the separation between logic and error handling. I also took the chance to couple clojure.test with test.check, for some basic property-based testing, and lein-eftest to have fast and pretty test results.

The setup is completed by the continuous integration offered by Travis CI and Deps Versions to identify outdated dependencies. Everything is available on GitHub, if you want to dig deeper into the details.

boodle is currently deployed on my home server, and in the last months it has proved to be a reliable tool. It also deepened my love for Clojure and ClojureScript. Long forgotten are the days where separation of concerns, both client- and server-side, seemed impossible and destined to fail.

-1:-- boodle (Post)--L0--C0--November 26, 2017 12:00 AM

emacspeak: Emacspeak 47.0 (GentleDog) Unleashed!

Emacspeak 47.0—GentleDog—Unleashed!

*For Immediate Release:

San Jose, Calif., (November 22, 2017)

Emacspeak 47.0 (GentleDog):
Redefining Accessibility In The Age Of User-Aware Interfaces
–Zero cost of Ownership makes priceless software Universally affordable!

Emacspeak Inc (NASDOG: ESPK) —
— announces the immediate world-wide availability of Emacspeak 47.0
(GentleDog) — a powerful audio desktop for leveraging today's
evolving Data, Social and Assistant-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
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
ubiquitous assistance, Web-surfing, blogging, social computing and
electronic messaging into the audio desktop, Emacspeak enables speech
access to local and remote information with a consistent and
well-integrated user interface. A rich suite of task-oriented tools
provides efficient speech-enabled access to the evolving
assistant-oriented social Internet cloud.

3 Major Enhancements:

This version requires emacs-25.1 or later.

  1. speech-Enable Extensible EVIL — VI Layer: ⸎
  2. Bookshare — Support Additional downloads (epub3,mp3): 🕮
  3. Bookmark support for EBooks in EWW 📔
  4. Speech-Enable VDiff — A Diff tool: ≏
  5. Speech-enable Package shx —Shell Extras For Emacs: 🖁
  6. Updated IDO Support: ⨼
  7. Implemented NOAA Weather API: ☔
  8. Speech-Enable Typographic Editting Support: 🖶
  9. Speech-Enable Package Origami: 🗀
  10. Magit Enhancements for Magitians: 🎛
  11. Speech-Enable RipGrep Front-End: ┅
  12. Added SmartParen Support: 〙
  13. Speech-enabled Minesweeper game: 🤯

    • 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
evolves, both upgrades and downgrades continue to be available at
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:

Emacspeak can be downloaded from GitHub –see you can visit Emacspeak on the
WWW at You can subscribe to the emacspeak
mailing list — — by sending mail to the
list request address The Emacspeak
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 47.0 (GentleDog) goes the next step in being helpful
    while letting users learn and grow.
  • 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
    efficient access to large amounts of readable Web content.
  • Emacspeak 39.0 continues the Emacspeak tradition of increasing the breadth of
    user tasks that are covered without introducing unnecessary
  • 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)
    established a new beach-head with respect to rapid task completion in
    an eyes-free environment.
  • Emacspeak-33.0 AKA StarDog brings
    unparalleled cloud access to the audio desktop.
  • Emacspeak 32.0 AKA
    LuckyDog continues to innovate via open technologies for better
  • Emacspeak 31.0 AKA TweetDog — adds tweeting to the Emacspeak
  • 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
    releases obsolete and downgrades unnecessary.
  • Emacspeak 26—AKA
    LeadDog—continues the tradition of introducing innovative access
    solutions that are unfettered by the constraints inherent in
    traditional adaptive technologies.
  • Emacspeak 25 —AKA ActiveDog
    —re-activates open, unfettered access to online
  • 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
  • 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
  • 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
  • Emacspeak-17.0 –code named HappyDog– enhances user
    productivity by exploiting today's evolving WWW
  • Emacspeak-16.0 –code named CleverDog– the follow-up to
    SmartDog– continued the tradition of working better, faster,
  • 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
    access to Webformation.
  • 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.

8 About Emacspeak:

Originally based at Cornell (NY) — —home to Auditory User
Interfaces (AUI) on the WWW, Emacspeak is now maintained on GitHub 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.

*About This Release:

Windows-Free (WF) is a favorite battle-cry of The League Against
Forced Fenestration (LAFF). –see 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 47.0 (GentleDog) Unleashed! (Post T. V. Raman ( 22, 2017 12:42 AM

Pragmatic Emacs: Pop up a quick shell with shell-pop

There are several ways of running a shell inside Emacs. I don’t find that I need to use it very often as I do so much within Emacs these days, but when I do it’s handy to quickly bring up the shell, run a command the then dismiss it again. The shell-pop package does this very smartly. One key combo (I use C-t) pops up a shell window for the directory containing the file you are currently editing, and then C-t dismisses the shell window when you are done.

The github page has lots of details on how to configure it, and I use a fairly minimal setup and use the ansi-term terminal emulator and zsh as my shell. Here is my configuration:

(use-package shell-pop
  :bind (("C-t" . shell-pop))
  (setq shell-pop-shell-type (quote ("ansi-term" "*ansi-term*" (lambda nil (ansi-term shell-pop-term-shell)))))
  (setq shell-pop-term-shell "/bin/zsh")
  ;; need to do this manually or not picked up by `shell-pop'
  (shell-pop--set-shell-type 'shell-pop-shell-type shell-pop-shell-type))

The last line is needed but I can’t remember where I got it from!

-1:-- Pop up a quick shell with shell-pop (Post Ben Maughan)--L0--C0--November 20, 2017 10:06 PM

Flickr tag 'emacs': GAMS mode: the basic screenshot.

shiro.takeda posted a photo:

GAMS mode: the basic screenshot.

Screenshots of GAMS mode for Emacs.

-1:-- GAMS mode: the basic screenshot. (Post shiro.takeda ( 19, 2017 07:25 AM

Flickr tag 'emacs': GAMS mode: the basic screenshot.

shiro.takeda posted a photo:

GAMS mode: the basic screenshot.

Screenshots of GAMS mode for Emacs.

-1:-- GAMS mode: the basic screenshot. (Post shiro.takeda ( 19, 2017 07:25 AM

punchagan: Multiple remotes with nullmailer

This a reference for future-me, and possibly someone pulling off an all-nighter trying to get nullmailer to use the correct “remote”.

What is nullmailer and why use it?

Nullmailer is a simple mail transfer agent that can forward mail to a remote mail server (or a bunch of them).

I use Emacs to send email, and it can be configured to talk to a remote SMTP server to send email. But, this blocks Emacs until the email is sent and the connection closed. This is annoying, and having nullmailer installed locally basically lets Emacs delegate this job without blocking.

Why multiple remotes?

I have multiple email accounts, and I’d like to use the correct remote server for sending email based on the FROM address.

I expected nullmailer to have some configuration to be able to specify this. But, it turns out that nullmailer just forwards the email to all the configured remotes until one of them succeeds.

How do we, then, send email from the correct remote SMTP server?

Currently, I have two remotes - my personal domain ( and GMail.

Having GMail as the first remote in nullmailer’s configuration wouldn’t let me send emails from my personal domain. GMail seems to agree to send the email coming from, but overwrite the MAIL FROM address and change it to my GMail address.

So, has to be the first remote. But, this server also seemed to accept and send emails with a FROM address. This was causing emails sent from my GMail ID to go into spam, as expected.

I had to reconfigure this mail server to reject relaying mails that didn’t belong to the correct domain names – i.e., reject relaying emails which had in the FROM address.

smtpd_sender_restrictions had to modified to have reject_sender_login_reject along with other values, and the smtpd_sender_login_maps had to be set to allow only the domain. This serverfault answer explains this in more detail.

-1:-- Multiple remotes with nullmailer (Post)--L0--C0--November 17, 2017 11:20 PM

William Denton: Org clocktables II: Summarizing a month

In Org clocktables I: The daily structure I explained how I track my time working at an academic library, clocking in to projects that are either categorized as PPK (“professional performance and knowledge,” our term for “librarianship,”), PCS (“professional contributions and standing”, which covers research, professional development and the like) and Service. I do this by checking in and out of tasks with the magic of Org.

I’ll add a day to the example I used before, to make it more interesting. This is what the raw text looks like:

* 2017-12 December

** [2017-12-01 Fri]
CLOCK: [2017-12-01 Fri 09:30]--[2017-12-01 Fri 09:50] =>  0:20
CLOCK: [2017-12-01 Fri 13:15]--[2017-12-01 Fri 13:40] =>  0:25

*** PPK

**** Libstats stuff
CLOCK: [2017-12-01 Fri 09:50]--[2017-12-01 Fri 10:15] =>  0:25

Pull numbers on weekend desk activity for A.

**** Ebook usage
CLOCK: [2017-12-01 Fri 13:40]--[2017-12-01 Fri 16:30] =>  2:50

Wrote code to grok EZProxy logs and look up ISBNs of Scholars Portal ebooks.

*** PCS

*** Service

**** Stewards' Council meeting
CLOCK: [2017-12-01 Fri 10:15]--[2017-12-01 Fri 13:15] =>  3:00

Copious meeting notes here.

** [2017-12-04 Mon]
CLOCK: [2017-12-04 Mon 09:30]--[2017-12-04 Mon 09:50] =>  0:20
CLOCK: [2017-12-04 Mon 12:15]--[2017-12-04 Mon 13:00] =>  0:45
CLOCK: [2017-12-04 Mon 16:00]--[2017-12-04 Mon 16:15] =>  0:15

*** PPK

**** ProQuest visit
CLOCK: [2017-12-04 Mon 09:50]--[2017-12-04 Mon 12:15] =>  2:25

Notes on this here.

**** Math print journals
CLOCK: [2017-12-04 Mon 16:15]--[2017-12-04 Mon 17:15] =>  1:00

Check current subs and costs; update list of print subs to drop.

*** PCS

**** Pull together sonification notes
CLOCK: [2017-12-04 Mon 13:00]--[2017-12-04 Mon 16:00] =>  3:00

*** Service

All raw Org text looks ugly, especially all those LOGBOOK and PROPERTIES drawers. Don’t let that put you off. This is what it looks like on my screen with my customizations (see my .emacs for details):

Much nicer in Emacs. Much nicer in Emacs.

At the bottom of the month I use Org’s clock table to summarize all this.

#+BEGIN: clocktable :maxlevel 3 :scope tree :compact nil :header "#+NAME: clock_201712\n"
#+NAME: clock_201712
| Headline             | Time  |      |      |
| *Total time*           | *14:45* |      |      |
| 2017-12 December     | 14:45 |      |      |
| \_  [2017-12-01 Fri] |       | 7:00 |      |
| \_    PPK            |       |      | 3:15 |
| \_    Service        |       |      | 3:00 |
| \_  [2017-12-04 Mon] |       | 7:45 |      |
| \_    PPK            |       |      | 3:25 |
| \_    PCS            |       |      | 3:00 |

I just put in the BEGIN/END lines and then hit C-c C-c and Org creates that table. Whenever I add some more time, I can position the pointer on the BEGIN line and hit C-c C-c and it updates everything.

Now, there are lots of commands I could use to customize this, but this is pretty vanilla and it suits me. It makes it clear how much time I have down for each day and how much time I spent in each of the three pillars. It’s easy to read at a glance. I fiddled with various options but decided to stay with this.

It looks like this on my screen:

Much nicer in Emacs. Much nicer in Emacs.

That’s a start, but the data is not in a format I can use as is. The times are split across different columns, there are multiple levels of indents, there’s a heading and a summation row, etc. But! The data is in a table in Org, which means I can easily ingest it and process it in any language I choose, in the same Org file. That’s part of the power of Org: it turns raw data into structured data, which I can process with a script into a better structure, all in the same file, mixing text, data and output.

Which language, though? A real Emacs hacker would use Lisp, but that’s beyond me. I can get by in two languages: Ruby and R. I started doing this in Ruby, and got things mostly working, then realized how it should go and what the right steps were to take, and switched to R.

Here’s the plan:

  • ignore “Headline” and “Total time” and “2017-12 December” … in fact, ignore everything that doesn’t start with “\_”
  • clean up the remaining lines by removing “\_”
  • the first line will be a date stamp, with the total day’s time in the first column, so grab it
  • after that, every line will either be a PPK/PCS/Service line, in which case grab that time
  • or it will be a new date stamp, in which case capture that information and write out the previous day’s information
  • continue on through all the lines
  • until the end, at which point a day is finished but not written out, so write it out

I did this in R, using three packages to make things easier. For managing the time intervals I’m using hms, which seems like a useful tool. It needs to be a very recent version to make use of some time-parsing functions, so it needs to be installed from GitHub. Here’s the R:

library(hms) ## Right now, needs GitHub version
clean_monthly_clocktable <- function (raw_clocktable) {
  ## Clean up the table into something simple
  clock <- raw_clocktable %>% filter(grepl("\\\\_", Headline)) %>% mutate(heading = str_replace(Headline, "\\\\_ *", "")) %>% mutate(heading = str_replace(heading, "] .*", "]")) %>% rename(total = X, subtotal = X.1) %>% select(heading, total, subtotal)

  ## Set up the table we'll populate line by line
  newclock <- tribble(~date, ~ppk, ~pcs, ~service, ~total)

  ## The first line we know has a date and time, and always will
  date_old <- substr(clock[1,1], 2, 11)
  total_time_old <- clock[1,2]
  date_new <- NA
  ppk <- pcs <- service <- vacation <- total_time_new <- "0:00"

  ## Loop through all lines ...
  for (i in 2:nrow(clock)) {
    if      (clock[i,1] == "PPK")     { ppk      <- clock[i,3] }
    else if (clock[i,1] == "PCS")     { pcs      <- clock[i,3] }
    else if (clock[i,1] == "Service") { service  <- clock[i,3] }
    else {
     date_new <- substr(clock[i,1], 2, 11)
     total_time_new <- clock[i,2]
    ## When we see a new date, add the previous date's details to the table
    if (! {
     newclock <- newclock %>% add_row(date = date_old, ppk, pcs, service, total = total_time_old)
     ppk <- pcs <- service <- "0:00"
     date_old <- date_new
     date_new <- NA
     total_time_old <- total_time_new

  ## Finally, add the final date to the table, when all the rows are read.
  newclock <- newclock %>% add_row(date = date_old, ppk, pcs, service, total = total_time_old)
  newclock <- newclock %>% mutate(ppk = parse_hm(ppk), pcs = parse_hm(pcs), service = parse_hm(service), total = parse_hm(total), lost = as.hms(total - (ppk + pcs + service))) %>% mutate(date = as.Date(date))

All of that is in a SRC block like below, but I separated the two in case it makes the syntax highlighting clearer. I don’t think it does, but such is life. Imagine the above code pasted into this block:

#+BEGIN_SRC R :session :results values


Running C-c C-c on that will produce no output, but it does create an R session and set up the function. (Of course, all of this will fail if you don’t have R (and those three packages) installed.)

With that ready, now I can parse that monthly clocktable by running C-c C-c on this next source block, which reads in the raw clock table (note the var setting, which matches the #+NAME above), parses it with that function, and outputs cleaner data. I have this right below the December clock table.

#+BEGIN_SRC R :session :results values :var clock_201712=clock_201712 :colnames yes

|       date |      ppk |      pcs |  service |    total |     lost |
| 2017-12-01 | 03:15:00 | 00:00:00 | 03:00:00 | 07:00:00 | 00:45:00 |
| 2017-12-04 | 03:25:00 | 03:00:00 | 00:00:00 | 07:45:00 | 01:20:00 |

This is tidy data. It looks this this:

Again, in Emacs Again, in Emacs

That’s what I wanted. The code I wrote to generate it could be better, but it works, and that’s good enough.

Notice all of the same dates and time durations are there, but they’re organized much more nicely—and I’ve added “lost.” The “lost” count is how much time in the day was unaccounted for. This includes lunch (maybe I’ll end up classifying that differently), short breaks, ploughing through email first thing in the morning, catching up with colleagues, tidying up my desk, falling into Wikipedia, and all those other blocks of time that can’t be directly assigned to some project.

My aim is to keep track of the “lost” time and to minimize it, by a) not wasting time and b) properly classifying work. Talking to colleagues and tidying my desk is work, after all. It’s not immortally important work that people will talk about centuries from now, but it’s work. Not everything I do on the job can be classified against projects. (Not the way I think of projects—maybe lawyers and doctors and the self-employed think of them differently.)

The one technical problem with this is that when I restart Emacs I need to rerun the source block with the R function in it, to set up the R session and the function, before I can rerun the simple “update the monthly clocktable” block. However, because I don’t restart Emacs very often, that’s not a big problem.

The next stage of this is showing how I summarize the cleaned data to understand, each month, how much of my time I spent on PPK, PCS and Service. I’ll cover that in another post.

-1:-- Org clocktables II: Summarizing a month (Post William Denton)--L0--C0--November 17, 2017 04:46 AM

Timo Geusch: Emacs on the Linux Subsystem for Windows

I’ve had the Linux Subsystem for Windows enabled for quite a while during the time it was in Beta. With the release of the Fall Creators Update, I ended up redoing my setup from scratch. As usual I grabbed Emacs Read More

The post Emacs on the Linux Subsystem for Windows appeared first on The Lone C++ Coder's Blog.

-1:-- Emacs on the Linux Subsystem for Windows (Post Timo Geusch)--L0--C0--November 15, 2017 01:48 PM

Chen Bin (redguardtoo): counsel-etags v1.3.1 is released

Counsel-etags is a generic solution for code navigation in Emacs.

It basically needs no setup. For example, one command counsel-etags-find-tag-at-point is enough to start code navigation immediately.

The package solves all the problems using Ctags/Etags with Emacs.

Problem 1: Ctags takes a few seconds to update the tags file (the index file to lookup tags). The updating process blocks the user's further interaction. This problem is solved by the virtual updating function from counsel-etags. The setup is simple:

;; Don't ask before rereading the TAGS files if they have changed
(setq tags-revert-without-query t)
;; Don't warn when TAGS files are large
(setq large-file-warning-threshold nil)
;; Setup auto update now
(add-hook 'prog-mode-hook
  (lambda ()
    (add-hook 'after-save-hook
              'counsel-etags-virtual-update-tags 'append 'local)))
(add-hook 'after-save-hook 'counsel-etags-virtual-update-tags)

Problem 2: Tag lookup may fail if the latest code is not scanned yet. This problem is solved by running counsel-etags-grep automatically if counsel-etags-find-tag-at-point fails. So users always get results.

There are also other enhancements.

Enhancement 1: Levenshtein Distance algorithm is used to place the better matching candidates at the the top. For example, a function named renderTable could be defined all around in a ReactJS project. But it's very possible the user prefers the definition in same component or same folder where she triggers code navigation.

Enhancement 2: It's inefficient to search the same tag again and again. counsel-etags-recent-tag is used to jump to previous definitions.

Enhancement 3: Ivy-mode provides filter UI for counsel-etags. Its means all the functionalities from Ivy is also available. For example, users can input "!keyword1" to exclude candidates matching "keyword1".

Enhancement 4: counsel-etags-grep uses the fastest grep program ripgrep if it's installed. Or else it falls back to standard grep.

Please check for more tips.

-1:-- counsel-etags v1.3.1 is released (Post Chen Bin)--L0--C0--November 12, 2017 09:40 AM

Benjamin Slade: More pdf-tools tricks

Following a couple of recent postings on pdf-tools, here are a few customisations I've found handy.

For scanned pdfs, 'pdf-view-auto-slice-minor-mode can be useful to turn on. You might bind it to something like s a. It auto trims the borders for each page of the pdf as it encounters them.

The following sets up a variety of colour-filter modes (good for night-time viewing, or anytime really that you don't want your eyeballs blasted with blazing white light):

;; midnite mode hook
(add-hook 'pdf-view-mode-hook (lambda ()
(pdf-view-midnight-minor-mode))) ; automatically turns on midnight-mode for pdfs

(setq pdf-view-midnight-colors '("#ff9900" . "#0a0a12" )) ; set the amber profile as default (see below)

(defun bms/pdf-no-filter ()
"View pdf without colour filter."
(pdf-view-midnight-minor-mode -1)

;; change midnite mode colours functions
(defun bms/pdf-midnite-original ()
"Set pdf-view-midnight-colors to original colours."
(setq pdf-view-midnight-colors '("#839496" . "#002b36" )) ; original values

(defun bms/pdf-midnite-amber ()
"Set pdf-view-midnight-colors to amber on dark slate blue."
(setq pdf-view-midnight-colors '("#ff9900" . "#0a0a12" )) ; amber

(defun bms/pdf-midnite-green ()
"Set pdf-view-midnight-colors to green on black."
(setq pdf-view-midnight-colors '("#00B800" . "#000000" )) ; green

(defun bms/pdf-midnite-colour-schemes ()
"Midnight mode colour schemes bound to keys"
(local-set-key (kbd "!") (quote bms/pdf-no-filter))
(local-set-key (kbd "@") (quote bms/pdf-midnite-amber))
(local-set-key (kbd "#") (quote bms/pdf-midnite-green))
(local-set-key (kbd "$") (quote bms/pdf-midnite-original))

(add-hook 'pdf-view-mode-hook 'bms/pdf-midnite-colour-schemes)

This automatically sets pdf-tools to display using the midnight mode amber filter.
You can return to the original/no-filter with "!" (i.e. S-1); set amber filter with "@" (i.e. S-2); set green filter with "#" (i.e. S-3); set the bluish original midnight mode colours with "$" (i.e. S-4). See below for screenshots of these different settings.

You also probably want to set the pdf-annot-default-markup-annotation-properties color to "#ff0000", as well as the pdf-annot-default-text-annotation-properties color to "#ff0000". This is a colour that is actually visible in the midnight-modes. If you go with the default yellow for markup it will not be easily visible in any of these colour-filter modes.
-1:-- More pdf-tools tricks (Post be_slayed ( 11, 2017 10:49 PM

Benjamin Slade: Take Elfeed everywhere: Mobile rss reading Emacs-style (for free/cheap)

After the demise of Google Reader, I switched for some time to NewsBlur. Unfortunately, its Android app never worked well for me. And integrating more of my life into Emacs is always desirable, so once I saw there was an Android interface for the fantastic Emacs RSS reader Elfeed, I made the switch.

The tricky thing with the Elfeed Android client is that it wants to connect to web interface of an instance of Elfeed running inside of Emacs. I could have done with my home computer, but that would require poking a hole through the firewall and in any case would be non-ideal when for instance I was travelling.

About a month ago I hit upon a cheap (in fact, free) solution for running a remote instance of Emacs running Elfeed that is connectable with the Android app. The VPS provider Wishosting offers an OpenVZ mini for $4/year, and if you stick a link to Wishosting on your own domain you can get it for free.

On my home desktop, work desktop, and laptop, I have Syncthing installed and I use this to keep the Elfeed database in sync between these machines.

In this blogpost I outline how to add a remote always-on instance of Elfeed running in Wishosting’s OpenVZ mini which also remains in sync with all of the other machines. (I use elfeed-org to organise my feeds, and just keep the file in ~/.elfeed/.) Just use Syncthing to keep the ~/.elfeed directory sync’ed between all of the machines (including any VPS’s).

I set up an Ubuntu 16.04 LTS VPS on Wishosting, and then installed Emacs and Syncthing, and that is what I would recommend.

  • Create your Ubuntu 16.04 LTS VPS.
  • Make a (non-root) user with superuser capability. Login with this user.
  • Install Emacs and Syncthing.
  • Configure Syncthing appropriately. You can connect remotely to the Web GUI.
  • Create and save a .emacs file in your user’s ~ with the following contents:
    ;; package setup here
    (require 'package)

    (package-initialize nil)
    (setq package-enable-at-startup nil)

    (add-to-list 'package-archives '("org" . "") t)

    (add-to-list 'package-archives
    '("melpa" . "") t)

    (add-to-list 'package-archives
    '("marmalade" .


    ;; general add packages to list
    (let ((default-directory "~/.emacs.d/elpa/"))

    ;; make sure 'use-package is installed
    (unless (package-installed-p 'use-package)
    (package-install 'use-package))

    ;;; use-package
    (require 'use-package)

    ;; Load elfeed
    (use-package elfeed
    :ensure t
    :bind (:map elfeed-search-mode-map
    ; ("A" . bjm/elfeed-show-all)
    ; ("E" . bjm/elfeed-show-emacs)
    ; ("D" . bjm/elfeed-show-daily)
    ("q" . bjm/elfeed-save-db-and-bury)))

    (require 'elfeed)

    ;; Load elfeed-org
    (use-package elfeed-org
    :ensure t
    (setq rmh-elfeed-org-files (list "~/.elfeed/"))

    ;; Laod elfeed-goodies
    (use-package elfeed-goodies
    :ensure t


    ;; Load elfeed-web
    (use-package elfeed-web
    :ensure t

    ;;; Elfeed
    (global-set-key (kbd "C-x w") 'bjm/elfeed-load-db-and-open)

    (define-key elfeed-show-mode-map (kbd "j") 'elfeed-goodies/split-show-next)
    (define-key elfeed-show-mode-map (kbd "k") 'elfeed-goodies/split-show-prev)
    (define-key elfeed-search-mode-map (kbd "j") 'next-line)
    (define-key elfeed-search-mode-map (kbd "k") 'previous-line)
    (define-key elfeed-show-mode-map (kbd "S-SPC") 'scroll-down-command)

    ;;write to disk when quiting
    (defun bjm/elfeed-save-db-and-bury ()
    "Wrapper to save the elfeed db to disk before burying buffer"

    ;;functions to support syncing .elfeed between machines
    ;;makes sure elfeed reads index from disk before launching
    (defun bjm/elfeed-load-db-and-open ()
    "Wrapper to load the elfeed db from disk before opening"

    (defun bjm/elfeed-updater ()
    "Wrapper to load the elfeed db from disk before opening"

    (run-with-timer 0 (* 30 60) 'bjm/elfeed-updater)

    (setq httpd-port NNNNN) ; replace NNNNN with a port equalling your start port + 10 (or whatever)

Note that you’ll need to configure the httpd-port appropriately as per the comment in the elisp above.
  • Then create the following systemd unit at ~/.config/systemd/user/emacs.service:
Description=Emacs: the extensible, self-documenting text editor

ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"

  • Enable and start this unit with:
$ systemctl --user enable --now emacs
  • And then make sure it runs persistently even when you’re not connected to your VPS via ssh (this tripped me up for some time):
# loginctl enable-linger USERNAME
  • Install the Elfeed Android app on your mobile, enter the app’s Settings, and put in whatever your Wishosting ip is plus the port you chose above (NNNNN), e.g., for the Elfeed web url.
  • That should be it. Now you’ll have access to your rss feed all over the world and Syncthing will ensure that all changes will be propagated to all of your Emacs instances including your VPS. These changes would include adding and deleting rss feeds and marking of posts as ’read’.
  • Note: on my desktops/laptop I use the following setup for Elfeed:
    ;; Load elfeed
    (use-package elfeed
    :ensure t
    :bind (:map elfeed-search-mode-map
    ; ("A" . bjm/elfeed-show-all)
    ; ("E" . bjm/elfeed-show-emacs)
    ; ("D" . bjm/elfeed-show-daily)
    ("q" . bjm/elfeed-save-db-and-bury)))

    (require 'elfeed)

    ;; Load elfeed-org
    (use-package elfeed-org
    :ensure t
    (setq rmh-elfeed-org-files (list "~/.elfeed/"))

    ;; Laod elfeed-goodies
    (use-package elfeed-goodies
    :ensure t


    ;; Load elfeed-web
    (use-package elfeed-web
    :ensure t

    ;;functions to support syncing .elfeed between machines
    ;;makes sure elfeed reads index from disk before launching
    (defun bjm/elfeed-load-db-and-open ()
    "Wrapper to load the elfeed db from disk before opening"

    ;;write to disk when quiting
    (defun bjm/elfeed-save-db-and-bury ()
    "Wrapper to save the elfeed db to disk before burying buffer"

    ;;; Elfeed
    (global-set-key (kbd "C-x w") 'bjm/elfeed-load-db-and-open)

    (define-key elfeed-show-mode-map (kbd ";") 'visual-fill-column-mode)

    (define-key elfeed-show-mode-map (kbd "j") 'elfeed-goodies/split-show-next)
    (define-key elfeed-show-mode-map (kbd "k") 'elfeed-goodies/split-show-prev)
    (define-key elfeed-search-mode-map (kbd "j") 'next-line)
    (define-key elfeed-search-mode-map (kbd "k") 'previous-line)
    (define-key elfeed-show-mode-map (kbd "S-SPC") 'scroll-down-command)
    ;; probably temporary: hack for elfeed-goodies date column:
    (defun elfeed-goodies/search-header-draw ()
    "Returns the string to be used as the Elfeed header."
    (if (zerop (elfeed-db-last-update))
    (let* ((separator-left (intern (format "powerline-%s-%s"
    (car powerline-default-separator-dir))))
    (separator-right (intern (format "powerline-%s-%s"
    (cdr powerline-default-separator-dir))))
    (db-time (seconds-to-time (elfeed-db-last-update)))
    (stats (-elfeed/feed-stats))
    (search-filter (cond
    (if (>= (window-width) (* (frame-width) elfeed-goodies/wide-threshold))
    (search-header/draw-wide separator-left separator-right search-filter stats db-time)
    (search-header/draw-tight separator-left separator-right search-filter stats db-time)))))

    (defun elfeed-goodies/entry-line-draw (entry)
    "Print ENTRY to the buffer."

    (let* ((title (or (elfeed-meta entry :title) (elfeed-entry-title entry) ""))
    (date (elfeed-search-format-date (elfeed-entry-date entry)))
    (title-faces (elfeed-search--faces (elfeed-entry-tags entry)))
    (feed (elfeed-entry-feed entry))
    (when feed
    (or (elfeed-meta feed :title) (elfeed-feed-title feed))))
    (tags (mapcar #'symbol-name (elfeed-entry-tags entry)))
    (tags-str (concat "[" (mapconcat 'identity tags ",") "]"))
    (title-width (- (window-width) elfeed-goodies/feed-source-column-width
    elfeed-goodies/tag-column-width 4))
    (title-column (elfeed-format-column
    title (elfeed-clamp
    (tag-column (elfeed-format-column
    tags-str (elfeed-clamp (length tags-str)
    (feed-column (elfeed-format-column
    feed-title (elfeed-clamp elfeed-goodies/feed-source-column-width

    (if (>= (window-width) (* (frame-width) elfeed-goodies/wide-threshold))
    (insert (propertize date 'face 'elfeed-search-date-face) " ")
    (insert (propertize feed-column 'face 'elfeed-search-feed-face) " ")
    (insert (propertize tag-column 'face 'elfeed-search-tag-face) " ")
    (insert (propertize title 'face title-faces 'kbd-help title)))
    (insert (propertize title 'face title-faces 'kbd-help title)))))
[Also posted at r/emacs]
-1:-- Take Elfeed everywhere: Mobile rss reading Emacs-style (for free/cheap) (Post be_slayed ( 11, 2017 10:44 PM

Ben Simon: Calculating Distance from a Cell Phone's Accelerometer - A failed, but fun attempt

Our gym had a nifty Bluetooth enabled jump rope that would report how many jumps you made in a session. Then the rope broke. This left me thinking: could I approximate the same thing by using the sensors on my phone?

Poking around, I learned that there's a class of app that gives you access to these sensors. In that genre, Physics Toolbox Suite appears to be a top pick. Launching the app gives me access to all sorts of data, from the gyroscope, to barometric pressure, to the GPS. It also gives me a way to record the data for a period of time, generating a simple CSV file. And if all that weren't enough, it's also ad free. To show my support, I just purchased the Pro version, even though the standard version does everything I need.

What caught my eye in the app was the Linear Accelerometer screen:

I've long since forgotten the majority of high school physics lessons, but I do know this: units matter. As the app reminded me (or perhaps taught me), acceleration is measured in meters per second, squared. What jumped out at me was the presence of meters, or distance. I now had my goal: rather than count the number of jumps in a jump-rope session, wouldn't it be far cooler to count distance? That is, how many vertical meters did I manage to conquer while jumping rope. I wasn't sure how I was going to tease this data out of the accelerometer, but I knew I was going to try.

The first stop in my journey was to head over to YouTube and learn how acceleration and distance are 'connected.' I found this Khan Academy video gave me enough background on distance, velocity and acceleration to let me derive a solution. The Physics Toolbox Suite app would give me a CSV file that provide an acceleration value every 100th of a second. Thinking through these concepts, I realized that I could at each moment derive speed and then distance, by looking at the change in time and acceleration. And because I knew that I was starting by standing still (that is, my velocity was zero), the whole system could be initialized and in theory, a final answer derived. I was quite proud of myself. Shira, for her part, rattled off the exact formula and explained to me that this super basic physics. Apparently, I could have skipped the Kahn Accademy, and just talked to her.

Now that I had a method for calculating distance via the accelerometer, I needed to try it in a controlled environment. I laid down a tape measure, and noted 4 meters. I then walked these 4 meters while capturing the accelerometer data via the Physics Toolbox app. With a few test runs captured, it was time to do the fun part: program the above solution.

Because the data was on my phone, I thought it appropriate to code the solution on my phone. I busted out tinyscheme, emacs and termux. Tinyscheme is a delightful tool to work with because it's so lean. This can also be a source of frustration, as to implement the above solution I needed a way of reading form a CSV file, and I'd rather not have to implement the string and file handling. Fortunately, I was able to borrow some code from the Programming Praxis Standard Prelude (thanks!), which meant that I didn't have to implement string-split or read-line.

The following function does the heavy lift for reading and parsing the CSV file:

;; Call handler on each row in the file.
;; Assume the first row is a header and the
;; following rows are all numeric data
(define (with-data file handler init)
  (define (wrap data)
    (lambda (index)
      (case index
 ((all) data)
 (else  (list-ref data index)))))
  (call-with-input-file file
    (lambda (port)
      (let ((header-row (read-line port)))
 (let loop ((line (read-line port))
     (accum (wrap init)))
   (cond ((eof-object? line) (accum 'all))
   (loop (read-line port)
         (wrap (handler
         (wrap (map string->number
      (string-split #\, line)))))))))))))

Ah, it's such a join programming this sort of thing in Scheme. It's like programming with Play-doh: you can invent new constructs with so little effort.

With the file parsing out of the way, it was time to write the actual code to calculate distance:

;; Use Physics 101 to calculate distance
;; based on the current acceleration, time
;; and velocity
(define (calculate-distance accum data)
  (let* ((t-now (data 0))
  (a-now (+
   (data 1)  ; ax 
   (data 2)  ; ay
   (data 3)  ; az
  (t-prev (accum 0))
  (v-prev (accum 1))
  (d-prev (accum 2))
  (t (- t-now t-prev))
  (v-now (+ v-prev (* a-now t)))
  (d-now (+ d-prev (* v-now t))))
    (list t-now v-now d-now)))

There's nothing particular sexy here. I'm taking in the time and acceleration data (via data) and using my accumulated values to calculate the current velocity and distance.

It was now time for the moment of truth. I ran the code against a sample data:

And, it was a bust. My code tells me that I covered 2.54 meters instead of the 4 meters I knew I covered.

I've been through the code a number of times, and I think the algorithm is fine. My guess is that I'm expecting too much accuracy out of my phone's sensor. Though, maybe my algorithm is fine and I just made a boneheaded mistake. You can see the full source code of the project here, and the data file is here.

Still, this exercise has been valuable. I learned about the Physics Toolbox app, which is definitely a keeper. I once again saw the amazing power of Termux, emacs, tinyscheme and how effortlessly they all come together on my cell phone. And I even learned some physics along the way.

While I think my goal of measuring how 'far' I jumped may not work. I'm still not convinced I can't use the sensors on my phone to at least count jumps. The data is there, the function to process the data file is ready, I just need to plug in right algorithm to make this all make sense.

Do you see where my assumptions on the accelerometer all fell apart? Please explain the comments!

-1:-- Calculating Distance from a Cell Phone's Accelerometer - A failed, but fun attempt (Post Ben Simon ( 09, 2017 04:21 PM

Raimon Grau: Finally publishing commit-msg-prefix.el

It's been a few months since I released commit-msg-prefix.
Just to remember a bit what was it about, I created a gif so that we all can relate again to it.

The user story is the following:

  • In your company/organisation, you have to follow some rule of prefixing all your commits with either a keyword (Add/Remove/Fix/Hotfix/Bump/Release) or an issue number, or something like that.
  • When you are about to commit that, you know what you just did (you should!), but you can't remember which particular issue number was that.
  • Then you go to jira/trello/github-issues/younameit and look for that and insert it.  
Usually, as it's been a long running issue, you have commits with that number, in your recent commit history, so an alternative to the last bullet point is to have a quick look at git log.

Well, commit-msg-prefix makes this automatically for you, so it shows the latest commits (filtered as you want), and lets you choose one (find-as-you-type provided by helm/ivy/ido), and inserts the first word of the commit.

Obviously, most of the relevant settings are configurable, so you can have support for fancier substitutions, or use mercurial logs.

The package itself is pretty simple, but it might be useful to others, and if it is, I'm happy to share it.  

I just issued the Pull Request for it to be in melpa, so more users can give it a try and I can test it a bit further. I hope it will be accepted  and will be available in melpa soon.

In the future, if it has some adoption, it might make sense to merge it into magit, but I don't want to bother magintainers when the idea is not widely tested yet.

Happy hacking!
-1:-- Finally publishing commit-msg-prefix.el (Post Raimon Grau ( 08, 2017 04:15 PM

William Denton: Org clocktables I: The daily structure


Recently I started tracking my time at work using Org’s clocking feature, and it’s working out very well. The actual act of tracking my time makes me much more focused, and I’m wasting less time and working more on important, planned, relevant things. It’s also helping me understand how much time I spend on each of the three main pillars of my work (librarianship + research and professional development + service). In order to understand all this well I wrote some code to turn the Org’s clocktable into something more usable. This is the first of two or three posts showing what I have.

Three pillars

In York University Libraries, where I work, librarians and archivists have academic status. We are not faculty (that’s the professors), but we’re very similar. We’re in the same union. We have academic freedom (important). We get “continuing appointment,” not tenure, but the process is much the same.

University professors have three pillars to their work: teaching, research and service. Service is basically work that contributes to the running of the university: serving on committees (universities have lots of committees, and they do important work, like vetting new courses and programs, allocating research funds, or deciding who gets tenure), being on academic governance bodies such as faculty councils and Senate, having a position in the union, etc. Usually there’s a 40/40/20 ratio on these three areas: people spend about 40% of their time on teaching, 40% on research and 20% on service. This fluctuates term to term and year to year—and person to person—but that’s the general rule in most North American universities, as I understand it.

Waiting for Sir Simon Rattle and the Berlin Philharmonic to enter Roy Thomson Hall, last November. Waiting for Sir Simon Rattle and the Berlin Philharmonic to enter Roy Thomson Hall, last November.

For librarians and archivists the situation can be different. Instead of teaching, let’s say we do “librarianship” as a catch-all term. (Or “archivy,” which the archivists assure me is a real word, but I still think it looks funny.) Then we also do professional development/research and service. In some places, like Laurentian, librarians have full parity with professors, and they have the 40/40/20 ratio. That is ideal. A regrettable example is Western, where librarians and archivists have to spend 75% of their time on professional work. That severely limits the contributions they can make both to the university and to librarianship and scholarship in general.

At York there is no defined ratio. For professors it’s understood to be the 40/40/20, but for librarians and archivists I think it’s understood that is not our ratio, but nothing is set out instead. (This, and that profs have a 2.5 annual course teaching load but we do not have an equivalent “librarianship load,” leads to problems.)

I have an idea of what the ratio should be, but I’m not going to say it here because this may become a bargaining issue. I didn’t know if my work matched that ratio because I don’t have exact details about how I spend my time. I’ve been doing a lot of service, but how much? How much of my time is spent on research?

This question didn’t come to me on my own. A colleague started tracking her time a couple of months ago, jotting things down each day. She said she hadn’t realized just how much damned time it takes to schedule things. I was inspired by her to start clocking my own time.

This is where I got to apply an aspect of Org I’d read about but never used. Org is amazing!

Work diary

I keep a file,, where I put notes on everything I do. I changed how I use subheadings and now I give every day this structure:

* 2017-12 December

** [2017-12-01 Fri]

*** PPK

*** PCS

*** Service

“PPK” is “professional performance and knowledge,” which is our official term for “librarianship” or “archivy.” “PCS” is “professional contribution and standing,” which is the umbrella term for research and more for faculty. Right now for us that pillar is called “professional development,” but that’s forty-year-old terminology we’re trying to change, so I use the term faculty use. (Check the T&P criteria for a full explanation.)

On my screen, because of my Emacs configuration, that looks like this:

Initial structure. Initial structure.

Clocking in

First thing in the morning, I create that structure, then under the date heading I run C-u C-u C-c C-x C-i (where C-c means Ctrl-c). Now, I realize that’s a completely ridiculous key combination to exist, but when you start using Emacs heavily, you get used to such incantations and they become second nature. C-c C-x C-i is the command org-clock-in. As the docs say, “With two C-u C-u prefixes, clock into the task at point and mark it as the default task; the default task will then always be available with letter d when selecting a clocking task.” That will make more sense in a minute.

When I run that command, Org adds a little block under the heading:

** [2017-12-01 Fri]
CLOCK: [2017-12-01 Fri 09:30]

*** PPK

*** PCS

*** Service

The clock is running, and a little timer shows up in my mode line that tells me how long I’ve been working on the current thing.

I’ll spend a while deleting email and checking some web sites, then let’s say I decide to respond to an email about reference desk statistics, because I can get it done before I have to head over to a 10:30 meeting. I make a new subheading under PPK, because this is librarianship work, and clock into it with C-c C-x C-i. The currently open task gets closed, the duration is noted, and a new clock starts.

** [2017-12-01 Fri]
CLOCK: [2017-12-01 Fri 09:30]--[2017-12-01 Fri 09:50] =>  0:20

*** PPK

**** Libstats stuff
CLOCK: [2017-12-01 Fri 09:50]

Pull numbers on weekend desk activity for A.

*** PCS

*** Service

(Remember this doesn’t look ugly the way I see it in Emacs. There’s another screenshot below.)

I work on that until 10:15, then I make a new task (under Service) and check into it (again with C-c C-x C-i). I’m going to a monthly meeting of the union’s stewards’ council, and walking to the meeting and back counts as part of the time spent. (York’s campus is pretty big.)

* [2017-12-01 Fri]
CLOCK: [2017-12-01 Fri 09:30]--[2017-12-01 Fri 09:50] =>  0:20

*** PPK

**** Libstats stuff
CLOCK: [2017-12-01 Fri 09:50]--[2017-12-01 Fri 10:15] =>  0;25

Pull numbers on weekend desk activity for A.

*** PCS

*** Service

**** Stewards' Council meeting
CLOCK: [2017-12-01 Fri 10:15]

The meeting ends at 1, and I head back to my office. Lunch was provided during the meeting (probably pizza or extremely bready sandwiches, but always union-made), so I don’t take a break for that. In my office I’m not ready to immediately settle into a task, so I hit C-u C-c C-x C-i (just the one prefix), which lets me “select the task from a list of recently clocked tasks.” This is where the d mentioned above comes in: a little list of recent tasks pops up, and I can just hit d to clock into the [2017-12-01 Fri] task.

** [2017-12-01 Fri]
CLOCK: [2017-12-01 Fri 09:30]--[2017-12-01 Fri 09:50] =>  0:20
CLOCK: [2017-12-01 Fri 13:15]

*** PPK

**** Libstats stuff
CLOCK: [2017-12-01 Fri 09:50]--[2017-12-01 Fri 10:15] =>  0:25

Pull numbers on weekend desk activity for A.

*** PCS

*** Service

**** Stewards' Council meeting
CLOCK: [2017-12-01 Fri 10:15]--[2017-12-01 Fri 13:15] =>  3:00

Copious meeting notes here.

Now I might get a cup of tea if I didn’t pick one up on the way, or check email or chat with someone about something. My time for the day is accruing, but not against any specific task. Then, let’s say it’s a focused day, and I settle in and work until 4:30 on a project about ebook usage. I clock in to that, then when I’m ready to leave I clock out of it with C-c C-x C-o.

** [2017-12-01 Fri]
CLOCK: [2017-12-01 Fri 09:30]--[2017-12-01 Fri 09:50] =>  0:20
CLOCK: [2017-12-01 Fri 13:15]--[2017-12-01 Fri 13:40] =>  0:25

*** PPK

**** Libstats stuff
CLOCK: [2017-12-01 Fri 09:50]--[2017-12-01 Fri 10:15] =>  0:25

Pull numbers on weekend desk activity for A.

**** Ebook usage
CLOCK: [2017-12-01 Fri 13:40]--[2017-12-01 Fri 16:30] =>  2:50

Wrote code to grok EZProxy logs and look up ISBNs of Scholars Portal ebooks.

*** PCS

*** Service

**** Stewards' Council meeting
CLOCK: [2017-12-01 Fri 10:15]--[2017-12-01 Fri 13:15] =>  3:00

Copious meeting notes here.

In Emacs, this looks much more appealing.

Final structure at end of day. Final structure at end of day.

That’s one day of time clocked. In my next post I’ll add another day and a clocktable, and then I’ll show the code I use to summarize it all into tidy data.


I’m doing all this for my own use, to help me be as effective and efficient and aware of my work habits as I can be. I want to spend as much of my time as I can working on the most important work. Sometimes that’s writing code, sometimes that’s doing union work, sometimes that’s chatting with a colleague about something that’s a minor thing to me but that takes an hour because it’s important to them, and sometimes that’s watching a student cry in my office and waiting for the moment when I can tell them that as stressful as things are right now it’s going to get better. (Women librarians get much, much more of this than men do, but I still get some. It’s a damned tough thing, doing a university degree.) I recommend my colleague Lisa Sloniowski’s award-winning article Affective Labor, Resistance, and the Academic Librarian (Library Trends Vol. 64, No. 4, 2016) for a serious look at all this.

-1:-- Org clocktables I: The daily structure (Post William Denton)--L0--C0--November 07, 2017 01:42 AM

Matthias Pfeifer: A maven plugin for Emacs

Introduction I am writing Java code with Emacs from time to time and normally miss a lot of the „sugar“ that „the other IDE I am using“ provides me with. From time to time I also stretch my fingers and try to improve my Emacs experience with some tooling. This resulted recently in a short […]
-1:-- A maven plugin for Emacs (Post Matthias)--L0--C0--November 02, 2017 08:45 PM

emacshorrors: bytecomp.el

It’s halloween, so here’s a real treat for you, the commentary in bytecomp.el! The author of that piece of code is Jamie Zawinski who did invaluable work for both GNU Emacs and XEmacs, these days he runs a night club and blogs. Here are my favorite parts of the file:

  • ";; We successfully didn't compile this file."
  • (insert "\n") ; aaah, unix.
  •             (when old-style-backquotes
                  (byte-compile-warn "!! The file uses old-style backquotes !!
    This functionality has been obsolete for more than 10 years already
    and will be removed soon.  See (elisp)Backquote in the manual."))
  • ;; Insert semicolons as ballast, so that byte-compile-fix-header
    ;; can delete them so as to keep the buffer positions
    ;; constant for the actual compiled code.
  • ;; To avoid consing up monstrously large forms at load time, we split
    ;; the output regularly.
  • ;; If things not being bound at all is ok, so must them being
    ;; obsolete.  Note that we add to the existing lists since Tramp
    ;; (ab)uses this feature.
  • ;; If foo.el declares `toto' as obsolete, it is likely that foo.el will
    ;; actually use `toto' in order for this obsolete variable to still work
    ;; correctly, so paradoxically, while byte-compiling foo.el, the presence
    ;; of a make-obsolete-variable call for `toto' is an indication that `toto'
    ;; should not trigger obsolete-warnings in foo.el.
  • ;; FIXME: we also use this hunk-handler to implement the function's dynamic
    ;; docstring feature.  We could actually implement it more elegantly in
    ;; byte-compile-lambda so it applies to all lambdas, but the problem is that
    ;; the resulting .elc format will not be recognized by make-docfile, so
    ;; either we stop using DOC for the docstrings of preloaded elc files (at the
    ;; cost of around 24KB on 32bit hosts, double on 64bit hosts) or we need to
    ;; build DOC in a more clever way (e.g. handle anonymous elements).
  • ;; Don't reload the source version of the files below
    ;; because that causes subsequent byte-compilation to
    ;; be a lot slower and need a higher max-lisp-eval-depth,
    ;; so it can cause recompilation to fail.
  • ;; To avoid "lisp nesting exceeds max-lisp-eval-depth" when bytecomp compiles
    ;; itself, compile some of its most used recursive functions (at load time).

Don’t get me wrong, I’m aware that these are all necessary and don’t indicate deeper faults in the source code. I merely find it interesting what hacks one has to come up with for byte-code compilation and found studying the file enlightening to say the least.

-1:-- bytecomp.el (Post Vasilij Schneidermann)--L0--C0--October 31, 2017 07:44 AM

Chen Bin (redguardtoo): Auto complete everything in Emacs

complete everything in Emacs :en:emacs:

As a web developer using modern front end framework like React/Angular, I spend a lot of time on web components.

A component instance is like:

  onSelectRow={ row => console.log(row) }
  onClickCell={ cell => console.log(cell) }
  <PaginationButtons />
  <TotalSum />
  <ReportButtons />

Basically a component instance is a big chunk of html tags.

I created a new package EACL (Emacs auto complete lines) which could help me input components in unbelievable speed.

The idea is simple. If I've already used one component elsewhere in the project. It's unnecessary to re-type the similar code again.

All I need to do is to input the first characters of the component and run M-x eacl-complete-tag which will grep the project and input the remaining part of component.

Here is a demo to input component ButtonToolbar:


Please note EACL is generic and can be use in any programming language.

M-x eacl-complete-statement to complete below Javascript code:

import {
} from 'react-bootstrap';

M-x eacl-complete-snippet to complete below C code:

static int v9fs_drop_inode(struct inode *inode)
    struct v9fs_session_info *v9ses;
    v9ses = v9fs_inode2v9ses(inode);
    if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
        return generic_drop_inode(inode);
     * in case of non cached mode always drop the
     * the inode because we want the inode attribute
     * to always match that on the server.
    return 1;

You can also create your own commands based on API eacl-complete-multi-lines-internal.

For example, it is a piece of cake to support Lisp by creating comand my-complete-lisp:

(require 'eacl)
(defun my-complete-lisp ()
  (eacl-complete-multi-lines-internal "[^)]*)"))
-1:-- Auto complete everything in Emacs (Post Chen Bin)--L0--C0--October 30, 2017 11:13 AM