Rubén Berenguel: 2019#13 Readings of the week

NOTE: The themes are varied, and some links below are affiliate links. Functional programming, adtech, history. Expect a similar wide range in the future as well. You can check all my weekly readings by checking the tag here . You can also get these as a weekly newsletter by subscribing here.

Photo by Mgg Vitchakorn on Unsplash

Ancient Chinese Buildings Are Held Together With Rice

As everyone who has prepared sticky rice and forgotten to clean the pan quickly knows.

'I'd Have These Extremely Graphic Dreams': What It's Like To Work On Ultra-Violent Games

Fatality burnout.

The Artistry of China’s Ivory Puzzle Balls

I’ve seen one from really close and they are amazing

Bristol academic cracks Voynich code

There was a rebuttal of this approach close to 2 years ago, but it still sounds interesting. Also, I’d expect phys.org to be somewhat trustable.

Technical Debt? Probably not.

Pay it off. Or not.

Scala's Future.successful: Do Not Block Your Future Success

Beware the future!

The Functional Scala Concurrency Challenge

Some of the solutions look neat, and there is something to be learnt in the diversity.

Technical overview of ads viewability measurement methods

I have always been interested into how ad viewability (if an ad is seen by a user or not) works. Now I know.

GraalVM installation and setup on macOS

GraalVM is a new Java runtime and compiler, which is somewhat faster than the normal JDK, and offers some really fancy cross-language options. I had been using RC9 or 10. It was time to update. I usually use Enterprise Edition for anything local, but can switch per-terminal with several aliases I have (j8, j11, jgree and jgrce) in case something breaks or I want to try another.

Caire - a content aware image resize library

Seam carving is so cool. I wrote a cropping system once, using PILs Haar cascade based object detection. It works pretty well for automated creation of ads, but seam carving is way better for almost all other cases.

🎥 Flare - Optimizing Apache Spark for Scale-Up Architectures and Medium-Size Data

I’m scared this will become a closed source, or business-on-top. Code is not available, but results are awesome. Luckily, the papers are (why the code is not as part of the papers is another question).

🎥 helm-edit

I had used multiple-cursors (and expand-region) in emacs many times, although I had a hard time making it work properly in spacemacs for a while. helm-edit works better already in spacemacs, so, big win!

🎥 Understanding Query Plans and Spark UIs

I knew everything in this video already, but it covers lots. Give it a look.

🎥 What the ƒ is a monad

Although focused on Java, it’s very well explained for any language. Of course, if you have do syntax or for comprehensions, better.

📚 The Great Mental Models

The audiobook by Shane Parrish, of FS Blog. It was good, but I expected something longer.

📚 The art of thinking in systems

If you have read Donna Meadows Thinking in Systems, this won’t give you anything new. And I’d rather recommend TiS.

Newsletter?

These weekly posts are also available as a newsletter. These days (since RSS went into limbo) most of my regular information comes from several newsletters I’m subscribed to, instead of me going directly to a blog. If this is also your case, subscribe by clicking here.
-1:-- 2019#13 Readings of the week (Post Ruben Berenguel (noreply@blogger.com))--L0--C0--May 21, 2019 09:42 PM

Rubén Berenguel: gtags (GNU global) in emacs for Scala

Photo by thom masat on Unsplash
As you may know, I’m a heavy emacs user, and a frequent Scala developer. Scala tooling for emacs was restricted to mostly ensime until recently. Although ensime is an excellent piece of software, it made my old Macbook suffer a lot (it only had 8gb of RAM). So, most of the time I just went hardcore mode developer, and worked with no autocompletion, no jump to definition, no-nothing. A pervasive use of ripgrep and good memory were sometimes enough, but I was envious of many things I could see in my colleagues using IntelliJ. Of course, switching editors was not an option.


I looked up what solutions were available, and the only option that seemed good enough was using the classic ctags/etags/gtags I hadn’t used since my C days.

Having a tags implementation can bring an almost-decent jump-to-definition essentially for free: gtags (and the others) work by pre-analysing the data and generating symbol maps which are usually stored as files, the overhead in speed and memory is minimal.

Installing it can get somewhat unintuitive (specially on Mac), since you need very specific settings for it to work with emacs and especially, Scala code.

Start by installing GNU global:
brew install global --with-pygments --with-ctags --with-exuberant-ctags
The key parts is having pygments.
Aside from this you will need to export the following environment variables:
GTAGSCONF=/usr/local/share/gtags/gtags.conf
GTAGSLABEL=pygments
Finally, you need to install (or activate) ggtags-mode. If you use spacemacs, you only need to activate the gtags layer.
All this has become moot as soon as metals has reached a usable state: now you can have a really fast language server for Scala, written in Scala with low memory overhead.
-1:-- gtags (GNU global) in emacs for Scala (Post Ruben Berenguel (noreply@blogger.com))--L0--C0--May 21, 2019 09:42 PM

Emacs Redux: Dealing with Jekyll Post URLs

A while ago I wrote about migrating Emacs Redux from Octopress to Jekyll. While I’m really happy with Jekyll overall, there has always been one thing that frustrated me a bit - namely linking to other posts. The syntax for this is the following:


{% post_url name-of-post %}

I know this probably doesn’t seem like a problem, but posts in Jekyll are usually prefixed with a timestamp (e.g. 2019-05-21-some-post ) which makes it really hard to get the name right without consulting the list of posts first. Luckily for us it’s trivial to write an Emacs command that helps with this.


(defun jekyll-insert-post-url ()
  (interactive)
  (let* ((files (remove "." (mapcar #'file-name-sans-extension (directory-files "."))))
         (selected-file (completing-read "Select article: " files nil t)))
    (insert (format "{%% post_url %s %%}" selected-file))))

Here’s how this command looks like in action:

jekyll_post_url.gif

I don’t know you, but I’m totally loving this. You can easily extend the core idea for all sorts of similar tasks that require transforming a bit the files in the current directory. Here’s a similar helper for dealing with image URLs:

(defun jekyll-insert-image-url ()
  (interactive)
  (let* ((files (directory-files "../assets/images"))
         (selected-file (completing-read "Select image: " files nil t)))
    (insert (format "![%s](/assets/images/%s)" selected-file selected-file))))

Let’s see this in action:

jekyll_image_url.gif

That’s all I have for you today! Meta-X forever!

-1:-- Dealing with Jekyll Post URLs (Post Bozhidar Batsov)--L0--C0--May 21, 2019 03:52 PM

Shae Erisson: mastermind in elisp

sketch of a mastermind game in elisp
-1:-- mastermind in elisp (Post Shae Erisson)--L0--C0--May 21, 2019 12:00 AM

sachachua: 2019-05-20 Emacs news

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

-1:-- 2019-05-20 Emacs news (Post Sacha Chua)--L0--C0--May 20, 2019 11:20 PM

Irreal: Magit in Spacemacs

Jack of Some is back with another video in his Absolute Minimum Series. This time, he takes a look at using Magit from within Spacemacs. Like his last video on Refactoring in Spacemacs, this one is applicable for all Emacs users whether or not you worship in the Church of Spacemacs, There are a couple of Spacemacsisms but they’re mainly the keystrokes to invoke Magit status.

Most of the action takes place in Magit which looks and works the same regardless of the Emacs installation you’re using. Jack covers all the “everyday” things that you need to do with Magit.

He starts off explaining how navigate on the Magit status page and bring up diffs for the files that have been changed. He continues with a demonstration of committing changes including how to commit just some of the parts of a changed file. Once he’s got his changes committed, he’s ready to push them upstream but, of course, he doesn’t want to push to the Master branch so he shows how to create and push to another branch instead.

His next topic is pulling and merging. He creates a repository and local copy that have conflicting changes. He uses that to show how to resolve merge conflicts using ediff. I particularly liked his exposition of that process.

Finally, he looks at git blame and stashing. Those are really simple operations that some tutorials make heavy going of but Jack shows how they’re simple and straightforward.

The video is 8 minutes, 25 seconds so it’s easy to watch it on a coffee break. I recommend it to all Magit users.

-1:-- Magit in Spacemacs (Post jcs)--L0--C0--May 20, 2019 04:21 PM

(with-emacs: Show matching lines when parentheses go off-screen

This posts will describe how I display lines matching off-screen parentheses at the top of the window:

demo

The variable blink-matching-paren can be used to configure the display of matching parentheses. If you look at the source, you will see that blink-paren-post-self-insert-function is added to post-self-insert-hook to do the job.

There are two things I would like to change about the way it works:

  1. When the matching paren goes off-screen, I usually look at the top of the window. Thus, this is the place where I would like to display the match information.

  2. The matching information should be displayed after movement commands as well.

First let’s take care of blink-matching-paren:

;; we will call `blink-matching-open` ourselves...
(remove-hook 'post-self-insert-hook
             #'blink-paren-post-self-insert-function)
;; this still needs to be set for `blink-matching-open` to work
(setq blink-matching-paren 'show)

As I already use show-paren-mode to visualize matching parentheses it makes sense to look for a way to hook into it. Because of that I decided to advice show-paren-function:

(let ((ov nil)) ; keep track of the overlay
  (advice-add
   #'show-paren-function
   :after
    (defun show-paren--off-screen+ (&rest _args)
      "Display matching line for off-screen paren."
      (when (overlayp ov)
        (delete-overlay ov))
      ;; check if it's appropriate to show match info,
      ;; see `blink-paren-post-self-insert-function'
      (when (and (overlay-buffer show-paren--overlay)
                 (not (or cursor-in-echo-area
                          executing-kbd-macro
                          noninteractive
                          (minibufferp)
                          this-command))
                 (and (not (bobp))
                      (memq (char-syntax (char-before)) '(?\) ?\$)))
                 (= 1 (logand 1 (- (point)
                                   (save-excursion
                                     (forward-char -1)
                                     (skip-syntax-backward "/\\")
                                     (point))))))
        ;; rebind `minibuffer-message' called by
        ;; `blink-matching-open' to handle the overlay display
        (cl-letf (((symbol-function #'minibuffer-message)
                   (lambda (msg &rest args)
                     (let ((msg (apply #'format-message msg args)))
                       (setq ov (display-line-overlay+
                                 (window-start) msg ))))))
          (blink-matching-open))))))

To create the overlay I have written the following helper function:

(defun display-line-overlay+ (pos str &optional face)
  "Display line at POS as STR with FACE.

FACE defaults to inheriting from default and highlight."
  (let ((ol (save-excursion
              (goto-char pos)
              (make-overlay (line-beginning-position)
                            (line-end-position)))))
    (overlay-put ol 'display str)
    (overlay-put ol 'face
                 (or face '(:inherit default :inherit highlight)))
    ol))

All that is left is to activate show-paren-mode with the settings you like:

(setq show-paren-style 'paren
      show-paren-delay 0.03
      show-paren-highlight-openparen t
      show-paren-when-point-inside-paren nil
      show-paren-when-point-in-periphery t)
(show-paren-mode 1)

To use the code of this post make sure to evaluate the code with lexical-scope.

-1:-- Show matching lines when parentheses go off-screen (Post clemera)--L0--C0--May 20, 2019 01:09 PM

Emacs Notes: Rectangle Commands: A handy tool for working with multi-columnar / tabular text

A Problem … and a Solution You are given this (1) a b c aaaa bb ccccc aaa bbb cccc aa bb ccc How would you generate this [ a , b , c ] [ aaaa, bb , ccccc ] [ aaa , bbb, cccc ] [ aa , bb , ccc ] A … Continue reading Rectangle Commands: A handy tool for working with multi-columnar / tabular text
-1:-- Rectangle Commands: A handy tool for working with multi-columnar / tabular text (Post Emacks)--L0--C0--May 19, 2019 02:57 PM

Endless Parentheses: What tests you shouldn’t write: an essay on negative tests

Software tests are great! I’m fortunate enough to have only worked with code-bases with reasonable-to-excellent test coverage, and I wouldn’t want to work in a world without tests. In fact, a thoroughly tested system is nothing short of liberating.

That said, tests are not free. I’m not talking about CI time, that is a cost but it’s usually reducible. Nor am I referring to the effort it takes to write the test, that’s a very real cost, but people are usually very mindful of that (it’s easy to take it into account the very real effort you’re having right now).

The cost that people tend to underestimate is the time wasted with false failures.

Let’s get the basics right. Tests are designed to fail. A test that never fails under any circumstance is a useless test. But there are good failures and bad failures. Which gets me to the entire point of this post.

Write tests with real failures

Real failures are good, false failures are bad.
You want a test to fail when you break functionality, not when you harmlessly change code.

Let’s start with a quick Ruby example. Consider a model with an attribute called value. It wouldn’t be surprising to see a test like this for such a model.

it { is_expected.to respond_to(:value) }

If you don’t know Rspec, this is roughly testing that you can call .value on the model.

But when will this test ever fail?
Under any reasonable condition, this will only fail if you rename the column in the database. Nobody will ever do that by accident!

What’s worse, this failure will never carry any useful information. It doesn’t tell the developer that this change is unexpectedly breaking something. All it ever does is give us yet another piece of code to fix while in the middle of an already long refactoring.

And how do we fix it? By editing the test to use the new name.

A false failure is one that you fix by editing the test, while a real failure is one you fix by editing the code.

False failures are unavoidable. Every test is exposed to them, and every time they happen the developer wastes some amount of time identifying and fixing the failure. That is a negative cost that every test carries and not everyone takes into account.

For most cases, we happily pay this cost because not having a test is way worse than having to fix it. Because one real failure preventing a bug from going live outweighs several false failures, adding up to a positive net effect.

But some tests (such as the example above) virtually never have real failures. Without any positive upside to them, they are strictly negative tests.

And how do we avoid negative tests?

Test function, not code

Let’s expand on our previous example.
Rails provides a helpful one-liner to validate the presence of a mandatory attribute.

validates :value, presence: true

That’s fine and good. The problem is when you see a similar one-liner testing that validation.

it { is_expected.to validate_presence_of(:value) }

Pause on that for a moment. We’ve written a spec to test a single line of code.

The only way that can fail is if we rename the attribute or remove the validation. Again, nobody is ever going to do that by accident. We’re not really testing that a specific functionality works as it should, we’re just testing that a particular line of code is written in a particular way.

That is a code test, not a function test, and code tests are negative tests.

A function test is one that verifies non-trivial functionality, functionality that could be accidentally broken by a number of reasons.

Testing the interface of a service, for instance, is basically always good. As there’s usually at least a few branching code paths inside it where one could inadvertently break a branch while editing another or while adding functionality.

Unit tests for simple functions and methods, in my opinion, are not no-brainers. People like to go nuts with them, because they’re easy to write and quick to run (so “why not?”), but a lot of them fall under the category of negative tests.

Unit tests are good when testing some reasonably complicated algorithm, as someone could actually break an edge case while trying to optimize the implementation. And even then, you shouldn’t just write a couple of mindless tests, as they will probably be negative. You should put some effort into figuring out the edge cases and testing them specifically.

Think before you test

Hopefully, you started thinking well before you wrote that first line of code, so there’s no reason to stop now just because you changed from the app/ to the specs/ directory.

Thinking and being mindful of what you’re testing will not only help you avoid negative tests, but will go a long way to making your positive tests more effective at catching the bugs they’re supposed to catch.

Comment on this.

-1:-- What tests you shouldn’t write: an essay on negative tests (Post)--L0--C0--May 19, 2019 12:00 AM

(or emacs: hydra 0.15.0 is out

This release consists of 45 commits done over the course of the last 2 years. With this version, I have introduced a Changelog.org, similar to what ivy and avy have.

hydra

Highlights

Display hints using posframe

A new defcustom hydra-hint-display-type was introduced that can be either lv (the default), message, or posframe.

Posframe is a package that leverages a new feature in Emacs 26.1: the ability to display child frames. The advantage of using child frames is that you can easily position them anywhere within your frame area. For example, the default setting is to put it in the center of the current window, which is closer to where your eyes are focused than the minibuffer. Child frames don't interfere with the content of the buffers which they overlap. Finally, you can select a different font for the child frame.

hydra-posframe

Less boilerplate in defhydra

You no longer have to add :hint nil, and you can skip the docstring as well:

(defhydra hydra-clock (:exit t)
  ("q" nil "quit" :column "Clock")
  ("c" org-clock-cancel "cancel" :column "Do" :exit nil)
  ("d" org-clock-display "display")
  ("e" org-clock-modify-effort-estimate "effort")
  ("i" org-clock-in "in")
  ("j" org-clock-goto "jump")
  ("o" org-clock-out "out")
  ("r" org-clock-report "report"))

Add heads to an existing hydra

You can now add heads to an existing hydra like this:

(defhydra hydra-extendable ()
  "extendable"
  ("j" next-line "down"))

(defhydra+ hydra-extendable ()
  ("k" previous-line "up"))

The new macro defhydra+ takes the same arguments as defhydra, so it's quite easy to split up or join your hydras.

The use case of defhydra+ is when you have many packages that want to add heads to an existing hydra. Some of them may be optional or loaded lazily.

You can now have a base defhydra, and then use defhydra+ to add heads to it when a new package is loaded. Example:

(defhydra hydra-toggle ()
  ("q" nil "quit" :column "Exit")
  ("w" whitespace-mode
       (format "whitespace-mode: %S" whitespace-mode)
       :column "Toggles"))

(use-package org
    :config
  (defhydra+ hydra-toggle ()
    ("l" org-toggle-link-display
         (format "org link display: %S" org-descriptive-links))))

Outro

Big thanks to all contributors, and I hope you enjoy the new release. Happy hacking!

PS. Thanks to everyone who supports me on Liberapay and Patreon!

-1:-- hydra 0.15.0 is out (Post)--L0--C0--May 17, 2019 10:00 PM

Irreal: An Emacs Journey

Someone tweeted a link to a 6-month-old post by Murat Demirbas, a computer scientist at SUNY Buffalo. The post, My Emacs Journey, describes Demirbas’ use of Emacs and his embracing of Org mode. He’s been using Emacs for over 20 years and says that he has reached the stage where his Emacs knowledge is mostly held in his muscle memory. He says that if you ask him what the key sequence for some command is, he can’t tell you until he types it and observes what he typed. I experience something similar: if you give me a key sequence and ask me what it does, I’ll have to stop and think and possibly won’t know even though I use it all the time without conscious effort. As Demirbas says, the knowledge is held in my muscle memory.

He writes at length about how Org mode changed his workflow. Like me, he uses it for writing, task management, and even to organize his thinking. I liked how he uses Org for his writing. It reminded me of a technique I’d forgotten about. When he’s writing a paper and defines a term, he turns it into a radio-target so that every time he uses it in the sequel, the new use gets turned into a link back to the definition. That’s a natural thing to do but I always forget about it.

I spent a long time reading his post because he had several interesting links to other posts or information. Take a look at his post to see what I mean.

-1:-- An Emacs Journey (Post jcs)--L0--C0--May 17, 2019 04:15 PM

sachachua: Adding :target option for the TOC keyword in Org Mode

Now that A- can be counted on to happily play with a babysitter for several hours once a week, I’ve decided to alternate consulting and personal projects. Two weeks ago, I used my personal time to make a script that renewed my library books automatically. This week, I set aside time to look at Org Mode. DC had asked me to update the patch I made to allow people to specify a target for the table of contents, and I was curious about whether I could hack something together.

Patch for adding :target to TOC keyword

Here’s a sample file that shows what I mean:

#+OPTIONS: toc:nil
* Not this section
** Heading X
** Heading Y
* Target
  :PROPERTIES:
  :CUSTOM_ID: TargetSection
  :END:
** Heading A
** Heading B
* Another section
#+TOC: headlines 1 :target "Target"

Here’s the core of how to make it work for HTML exports:

(defun org-html-keyword (keyword _contents info)
  "Transcode a KEYWORD element from Org to HTML.
CONTENTS is nil.  INFO is a plist holding contextual information."
  (let ((key (org-element-property :key keyword))
  (value (org-element-property :value keyword)))
    (cond
     ((string= key "HTML") value)
     ((string= key "TOC")
      (let ((case-fold-search t))
  (cond
   ((string-match "\\<headlines\\>" value)
    (let ((depth (and (string-match "\\<[0-9]+\\>" value)
          (string-to-number (match-string 0 value))))
    (scope
     (cond
      ;; link
      ((string-match ":target +\"\\([^\"]+\\)\"" value)
       (let ((link (with-temp-buffer
         (save-excursion
           (insert (org-make-link-string (match-string 1 value))))
         (org-element-link-parser))))
         (pcase (org-element-property :type link)
           ((or "custom-id" "id") (org-export-resolve-id-link link info))
           ("fuzzy" (org-export-resolve-fuzzy-link link info))
           (_ nil))))
      ;; local
      ((string-match-p "\\<local\\>" value) keyword))))
      (org-html-toc depth info scope)))
   ((string= "listings" value) (org-html-list-of-listings info))
   ((string= "tables" value) (org-html-list-of-tables info))))))))

It was a lot of fun Doing the Right Thing(s): writing documentation, adding tests, and making it work for more than just HTML export. I found out where to make the changes by using grep to search for TOC in the Org Mode source code. All the heavy lifting was already done by org-export-collect-headlines, so it was just a matter of passing the right scope. It took me a while to figure out that I needed to pass an Org link element. An easy way of making that element work for both fuzzy and ID-specific links was to insert the target text into a temporary buffer (remembering to use org-make-link-string) and then calling org-element-link-parser.

I tried figuring out how to make it work with a link to another file, but I didn’t get very far, so I figured I’d just wrap things up nicely there.

I wasn’t sure if my original post made it through because I sent it through Gmane and Cc:d DC, who got it with an empty To:, so I ended up submitting it twice. I just realized I forgot to add test-ox-ascii.el. I don’t want to spam the list, so I’ll send that along with other changes if people have feedback.

But look! Open source contributions! I’m so excited. I wonder what I’ll get to do in two weeks from now. =)

-1:-- Adding :target option for the TOC keyword in Org Mode (Post Sacha Chua)--L0--C0--May 15, 2019 08:17 PM

Manuel Uberti: It never occurred to me

Years of Emacs, and I am still learning something new that improves my daily workflow.

Recently I’ve had to deal with CSV files, generated by a little Clojure program using data from different databases. The CSV files are then imported in another database through a new shiny application bought by our customer. Data integration, exactly.

While the data extraction is just a matter of SQL queries, the CSV files must match the stringent requirements of the new application. We ended up with messy CSV files, close but not that close to the expected results. Needless to say, sometimes we have to edit the files manually, and this is where Emacs once again shines.

The problem is simple: how can I list only the matches I am looking for in a CSV file, without printing the whole lines the matches belong to? I need a clean list of occurrences, nothing more, because debugging these files is already painful as it is.

I am so used to swiper-isearch and counsel-rg that I tend to forget Emacs built-in occur. As per the documentation:

When NLINES is a string or when the function is called interactively with prefix argument without a number (`C-u' alone as prefix) the matching strings are collected into the *Occur* buffer by using NLINES as a replacement regexp.

So all is needed is pressing C-u M-s o (the equivalent of C-u M-x occur in my Emacs configuration), typing the string I am looking for and hitting RET. It doesn’t get easier than this.

-1:-- It never occurred to me (Post)--L0--C0--May 14, 2019 12:00 AM

Chen Bin (redguardtoo): My favorite Richard Stallman interviews

I've watched/listened many Richard Stallman interviews. Some hosts are really bad. They know nothing about technology and are too aggressive.

But good interviewers still exist. Here are top 3 interviews I recommend:

-1:-- My favorite Richard Stallman interviews (Post Chen Bin)--L0--C0--May 13, 2019 02:33 PM

Modern Emacs: Testing Emacs programs with Buttercup

Buttercup is a testing framework for emacs-lisp. It is used by large projects like Clojure's CIDER to write clean, concise, and descriptive tests. I introduce Buttercup and build up to advanced usages with the faint, unlikely dream that some Emacs programmer decides to add tests to their library... What is Buttercup? Introduction Buttercup's entry points are: describe, it, and expect. We describe a test suite with a name. Test cases within the possibly nested suites are done with it and assertions as expect blocks within.
-1:-- Testing Emacs programs with Buttercup (Post)--L0--C0--May 13, 2019 12:00 AM

Raimon Grau: ncdu vs dired-du-mode

ncdu a very nice utility that does what you probably want to do when you do 'du -sh *'  repeatedly in different directories.

ncdu allows for navigating through the directory structure seeing sizes and disk usage percentages of files and subdirectories. Also, has vi-friendly keybindings.

Of course, there's a way to do a very similar thing in emacs, which is using `dired-du-mode`. Take a look at the "c-x c-h" keybind to toggle human friendly numbers, and m-x dired-du-count-size to aggregate the sizes of all marked files.
-1:-- ncdu vs dired-du-mode (Post Raimon Grau (noreply@blogger.com))--L0--C0--May 12, 2019 08:39 AM

Marcin Borkowski: Toggling modeline clock display

As I mentioned a lot of times, I use Org-mode clocking all the time. Among others, I integrated it with two external services, I have a few dedicated keybindings to it in my Org-mode hydra. It’s no wonder that I work hard to make clocking as smooth as possible.
-1:-- Toggling modeline clock display (Post)--L0--C0--May 11, 2019 06:27 AM

Shae Erisson: xmonad the tiling window manager

setting up xmonad on ubuntu 19.04
-1:-- xmonad the tiling window manager (Post Shae Erisson)--L0--C0--May 11, 2019 12:00 AM

(or emacs: avy 0.5.0 is out

This release consists of 109 commits done over the course of the last 3 years by me and many contributors. Similarly to the 0.4.0 release, the release notes are in Changelog.org. I recommend reading them inside Emacs.

avy.png

Highlights

A lot of new code is just straight upgrades, you don't need to do anything extra to use them. Below, I'll describe the other part of the new code, which is new commands and custom vars.

New API functions

New functions have been added as drop-in replacements of double-dash (private) Avy functions that were used in other packages and configs. Please replace the references to the obsolete functions.

  • avy-jump is a drop-in replacement of avy--generic-jump,
  • avy-process is a drop-in replacement of avy--process.

New dispatch actions

The concept of dispatch actions was introduced in 0.4.0. Suppose you have bound:

(global-set-key (kbd "M-t") 'avy-goto-word-1)

and a word that starts with a "w" and is select-able with "a". Here's what you can do now:

  • M-t w a to jump there
  • M-t w x a - avy-action-kill-move: kill the word and move there,
  • M-t w X a - avy-action-kill-stay: kill the word without moving the point,
  • M-t w i a - avy-action-ispell: use ispell/flyspell to correct the word,
  • M-t w y a - avy-action-yank: yank the word at point,
  • M-t w t a - avy-action-teleport: kill the word and yank it at point,
  • M-t w z a - avy-action-zap-to-char: kill from point up to selected point.

You can customize avy-dispatch-alist to modify these actions, and also ensure that there's no overlap with your avy-keys, if you customized them.

New avy-style setting: 'words

You can now customize:

(setq avy-style 'words)

And you'll see overlays like "by", "if", "is", "it", "my" for 2-letter sequences, and "can", "car", "cog" for 3-letter sequences. You might find them easier to type than "hla", "lls" and "jhl". But you will have to adjust your avy-dispatch-alist, e.g. to use only upper case characters.

avy-style-words

avy-linum-mode

This is feature is a mix of linum-mode and ace-window-display-mode. You'll see the overlays when you enable this mode, so that there's less context switch when you call avy-goto-line.

Suppose you jumped to a word that starts with "a". Now you want to jump to a different word that also starts with "a". You can use avy-resume for this.

Additionally, you can use avy-next and avy-prev to cycle between the last avy candidates. Here's an example hydra to facilitate it:

(defhydra hydra-avy-cycle ()
  ("j" avy-next "next")
  ("k" avy-prev "prev")
  ("q" nil "quit"))

(global-set-key (kbd "C-M-'") 'hydra-avy-cycle/body)

Outro

Big thanks to all contributors, and I hope you enjoy the new release. Happy hacking!

-1:-- avy 0.5.0 is out (Post)--L0--C0--May 10, 2019 10:00 PM

Raimon Grau: preview files/links without changing the focus

I realized today that there's a consistent way (although not very intuitive to me) to peek (preview) a destination of a clickable thing without opening it. 

It's "C-o".  Of course, it is very useful for browsing and exploring purposes.  Just try it in dired, occur, ibuffer, rg, and probably many more.

In most of those modes "o" "opens" a buffer on the destination and gives the focus to it, so I guess "C-o" makes sense, it's just I'm so used to hit RET that I never think of "C-o".

Anyway, I hope you find this one helpful
-1:-- preview files/links without changing the focus (Post Raimon Grau (noreply@blogger.com))--L0--C0--May 09, 2019 12:50 PM

Phil Hagelberg: in which another game is jammed

All the games I've created previously have used the LÖVE framework, which I heartily recommend and have really enjoyed using. It's extremely flexible but provides just the right level of abstraction to let you do any kind of 2D game. I have even created a text editor in it. But for the 2019 Lisp Game Jam I teamed up again with Emma Bukacek (we first worked together on Goo Runner for the previous jam) and wanted to try something new: TIC-80.

tic-80 screenshot

TIC-80 is what's referred to as a "fantasy console"1; that is, a piece of software which embodies an imaginary computer which never actually existed. Hearkening back to the days of the Commodore 64, it has a 16-color palette, a 64kb limit on the amount of code you can load into it, and 80kb of space for data (sprites, maps, sound, and music). While these limitations may sound severe, the idea is that they can be liberating because there is no pressure to create something polished; the medium demands a rough, raw style.

The really impressive thing about TIC-80 you notice right away is how it makes game development so accessible. It's one file to download (or not even download; it runs perfectly fine in a browser) and you're off to the races; the code editor, sprite editor, mapper, sound editor, and music tracker are all built-in. But the best part is that you can explore other people's games (with the SURF command), and once you've played them, hit ESC to open the editor and see how they did it. You can make changes to the code, sprites, etc and immediately see them reflected. This kind of explore-and-tinker approach encourages you to experiment and see for yourself what happens.

In fact, try it now! Go to This is my Mech and hit ESC, then go down to "close game" and press Z to close it. You're in the console now, so hit ESC again to go to the editor, and press the sprite editor button at the top left. Change some of the character sprites, then hit ESC to go back to the console and type RUN to see what it does! The impact of the accessibility and immediacy of the tool simply can't be overstated; it calls out to be hacked and fiddled and tweaked.

Having decided on the platform, Emma and I threw around a few game ideas but landed on making an adventure/comedy game based on the music video I'll form the Head by MC Frontalot, which is in turn a parody of the 1980s cartoon Voltron, a mecha series about five different pilots who work together to form a giant robot that fights off the monster of the week. Instead of making the game about combat, I wanted a theme of cooperation, which led to a gameplay focused around dialog and conversation.

I'll form the head music video

I focused more on the coding and the art, and Emma did most of the writing and all of the music. One big difference when coding on TIC-80 games vs LÖVE is that you can't pull in any 3rd-party libraries; you have the Lua/Fennel standard library, the TIC-80 API, and whatever you write yourself. In fact, TIC-80's code editor supports only a single file. I'm mostly OK with TIC-80's limitations, but that seemed like a bit much, especially when collaborating, so I split out several different files and edited them in Emacs, using a Makefile to concatenate them together and TIC-80's "watch" functionality to load it in upon changes. In retrospect, while having functionality organized into different files was nice, it wasn't worth the downside of having the line numbers be incorrect, so I wouldn't do that part again.

The file watch feature was pretty convenient, but it's worth noting that the changes were only applied when you started a new game. (Not necessarily restarting the whole TIC-80 program, just the RUN command.) There's no way to load in new code from a file without restarting the game. You can evaluate new code with the EVAL command in the console and then RESUME to see the effect it has on a running game, but that only applies to a single line of code typed into the console, which is pretty limiting compared to LÖVE's full support for hot-loading any module from disk at any time that I wrote about previously. This was the biggest disadvantage of developing in TIC-80 by a significant margin. Luckily our game didn't have much state, so constantly restarting it wasn't a big deal, but for other games it would be.2

Another minor downside of collaborating on a TIC-80 game is that the cartridge is a single binary file. You can set it up so it loads the source from an external file, but the rest of the game (sprites, map, sound, and music) are all stored in one place. If you use git to track it, you will find that one person changing a sprite and another changing a music track will result in a conflict you can't resolve using git. Because of this, we would claim a "cartridge lock" in chat so that only one of us was working on non-code assets at a time, but it would be much nicer if changes to sprites could happen independently of changes to music without conflict.

screenshot of the game

Since the game consisted of mostly dialog, the conversation system was the central place to start. We used coroutines to allow a single conversation to be written in a linear, top-to-bottom way and react to player input but still run without blocking the main event loop. For instance, the function below moves the Adam character, says a line, and then asks the player a question which has two possible responses, and reacts differently depending on which response is chosen. In the second case, it sets convos.Adam so that the next time you talk to that character, a different conversation will begin:

(fn all.Adam2 []
  (move-to :Adam 48 25)
  (say "Hey, sorry about that.")
  (let [answer (ask "What's up?" ["What are you doing?"
                                  "Where's the restroom?"])]
    (if (= answer "Where's the restroom?")
        (say "You can pee in your pilot suit; isn't"
             "technology amazing? Built-in"
             "waste recyclers.")
        (= answer "What are you doing?")
        (do (say "Well... I got a bit flustered and"
                 "forgot my password, and now I'm"
                 "locked out of the system!")
            (set convos.Adam all.Adam25)
            (all.Adam25)))))

There was some syntactic redundancy with the questions which could have been tidied up with a macro. In older versions of Fennel, the macro system is tied to the module system, which is normally fine, but TIC-80's single-file restriction makes it so that style of macros were unavailable. Newer versions of Fennel don't have this restriction, but unfortunately the latest stable version of TIC-80 hasn't been updated yet. Hopefully this lands soon! The new version of Fennel also includes pattern matching, which probably would have made a custom question macro unnecessary.

The vast majority of the code is dialog/conversation code; the rest is for walking around with collision detection, and flying around in the end-game sequence. This is pretty standard animation fare but was a lot of fun to write!

rhinos animation

I mentioned TIC-80's size limit already; with such a dialog-heavy game we did run into that on the last day. We were close enough to the deadline with more we wanted to add that it caused a bit of a panic, but all we had to do was remove a bunch of commented code and we were able to squeeze what we needed in. Next time around I would use single-space indents just to save those few extra bytes.

All in all I think the downsides of TIC-80 were well worth it for a pixel-art style, short game. Being able to publish the game to an HTML file and easily publish it to itch.io (the site hosting the jam) was very convenient. It's especially helpful in a jam situation because you want to make it easy for as many people as possible to play your game so they can rate it; if it's difficult to install a lot of people won't do it. I've never done my own art for a game before, but having all the tools built-in convinced me to give it a try, and it turned out pretty good despite me not having any background in pixel art, or art of any kind.

Anyway, I'd encourage you to give the game a try. The game won first place in the game jam, and you can finish it in around ten minutes in your browser. And if it looks like fun, why not make your own in TIC-80?


[1] The term "fantasy console" was coined by PICO-8, a commercial product with limitations even more severe than TIC-80. I've done a few short demos with PICO-8 but I much prefer TIC-80, not just because it's free software, but because it supports Fennel, has a more comfortable code editor, and has a much more readable font. PICO-8 only supports a fixed-precision decimal fork of Lua. The only two advantages of PICO-8 are the larger community and the ability to set flags on sprites.

[2] I'm considering looking into adding support in TIC-80 for reloading the code without wiping the existing state. The author has been very friendly and receptive to contributions in the past, but this change might be a bit too much for my meager C skills.

-1:-- in which another game is jammed (Post Phil Hagelberg)--L0--C0--May 07, 2019 07:52 PM

Marcin Borkowski: A few Magit tips

A month ago I wrote about merging in Git without actually comitting the changes, and mentioned that you probably can’t do that from within Magit. It turned out that I was wrong – in fact, Magit can do it. More recently, I wrote about another Git tip, which is staging an empty file. Then, Nicolas Petton asked whether it’s possible in Magit, and lo and behold – it is, in a quite intuitive (and documented in the docstring) way I just didn’t think about.
-1:-- A few Magit tips (Post)--L0--C0--May 05, 2019 04:15 AM

emacspeak: Emacspeak 50.0 (SageDog) Unleashed!


Announcing Emacspeak 50.0—SageDog!

1 For Immediate Release:

San Jose, Calif., (May 4, 2019)


1.1 🦮 Emacspeak 50.0 (SageDog) Unleashed!

Advancing Accessibility In The Age Of User-Aware Interfaces — Zero
cost of Ownership makes priceless software Universally affordable!


Emacspeak Inc (NASDOG: ESPK) — http://github.com/tvraman/emacspeak
— announces the immediate world-wide availability of Emacspeak 50.0
(SageDog) — a powerful audio desktop for leveraging today's evolving
Data, Social and Assistant-Oriented Internet cloud.


🚭: Naturally Intelligent (NI)™ at how information is spoken, Emacspeak
is entirely free of Artificial Ingredients (AI)™.


2 Investors Note:

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


3 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.


4 Major Enhancements:

This version requires emacs-26.1 or later.

  1. Emacs 26 Support 🤻
  2. Updated URL templates 🕷
  3. Updated websearch wizards 🧙
  4. Updated Bookshare support 📚
  5. Updated EWW support 🕸
  6. Smart tabs for EWW 📑
  7. Speech-enables Forge for software development 🏭
  8. The ESpeak server now builds on the Mac 🔈
  9. Updated DBus support 🚌
  10. Speech-enable Github-Explorer 🤯
  11. Speech-enabled navi-mode 🌲

— And a lot more than will fit this margin. … 🗞


5 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.


6 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!”.


6.1 Note from Aster,Bubbles and Tilden:

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


7 Obtaining Emacspeak:

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


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


8 History:

  • Emacspeak 50.0 (SageDog) embraces the wisdom of stability as
    opposed to rapid change and the concomitant creation of bugs.
  • Emacspeak 49.0 (WiseDog) leverages the wisdom gleaned from
    earlier releases to provide an enhanced auditory experience.
  • Emacspeak 48.0 (ServiceDog) builds on earlier releases to provide
    continued end-user value.
  • 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
    bloatware.
  • Emacspeak 38.0 is the latest in a series of award-winning
    releases from Emacspeak Inc.
  • Emacspeak 37.0 continues the tradition of
    delivering robust software as reflected by its code-name.
  • Emacspeak 36.0 enhances the audio desktop with many new tools including full
    EPub support — hence the name EPubDog.
  • Emacspeak 35.0 is all about
    teaching a new dog old tricks — and is aptly code-named HeadDog in
    on of our new Press/Analyst contact. emacspeak-34.0 (AKA Bubbles)
    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
    access.
  • Emacspeak 31.0 AKA TweetDog — adds tweeting to the Emacspeak
    desktop.
  • Emacspeak 30.0 AKA SocialDog brings the Social Web to the
    audio desktop—you cant but be social if you speak!
  • Emacspeak 29.0—AKAAbleDog—is a testament to the resilliance and innovation
    embodied by Open Source software—it would not exist without the
    thriving Emacs community that continues to ensure that Emacs remains
    one of the premier user environments despite perhaps also being one of
    the oldest.
  • Emacspeak 28.0—AKA PuppyDog—exemplifies the rapid pace of
    development evinced by Open Source software.
  • Emacspeak 27.0—AKA
    FastDog—is the latest in a sequence of upgrades that make previous
    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
    information.
  • Emacspeak-Alive —AKA LiveDog —enlivens open, unfettered
    information access with a series of live updates that once again
    demonstrate the power and agility of open source software
    development.
  • Emacspeak 23.0 — AKA Retriever—went the extra mile in
    fetching full access.
  • Emacspeak 22.0 —AKA GuideDog —helps users
    navigate the Web more effectively than ever before.
  • Emacspeak 21.0
    —AKA PlayDog —continued the
    Emacspeak tradition of relying on enhanced
    productivity to liberate users.
  • Emacspeak-20.0 —AKA LeapDog —continues
    the long established GNU/Emacs tradition of integrated innovation to
    create a pleasurable computing environment for eyes-free
    interaction.
  • emacspeak-19.0 –AKA WorkDog– is designed to enhance
    user productivity at work and leisure.
  • Emacspeak-18.0 –code named
    GoodDog– continued the Emacspeak tradition of enhancing user
    productivity and thereby reducing total cost of
    ownership.
  • Emacspeak-17.0 –code named HappyDog– enhances user
    productivity by exploiting today's evolving WWW
    standards.
  • Emacspeak-16.0 –code named CleverDog– the follow-up to
    SmartDog– continued the tradition of working better, faster,
    smarter.
  • Emacspeak-15.0 –code named SmartDog–followed up on TopDog
    as the next in a continuing series of award-winning audio desktop
    releases from Emacspeak Inc.
  • Emacspeak-14.0 –code named TopDog–was

the first release of this millennium.

  • Emacspeak-13.0 –codenamed
    YellowLab– was the closing release of the
    20th. century.
  • Emacspeak-12.0 –code named GoldenDog– began
    leveraging the evolving semantic WWW to provide task-oriented speech
    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.

9 About Emacspeak:

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


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


10 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
http://www.usdoj.gov/atr/cases/f3800/msjudgex.htm for details on
the ill-effects of Forced Fenestration.


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


-1:-- Emacspeak 50.0 (SageDog) Unleashed! (Post T. V. Raman (noreply@blogger.com))--L0--C0--May 03, 2019 06:30 PM

emacshorrors: comint-process-echoes

Originally I planned to blog about a fun hack, porting the infamous cloud-to-butt browser extension to Emacs. The idea was that whenever you interact with subprocesses instances of “cloud” would be replaced with “butt”, I picked shell.el for ease of hacking[1]. The following snippet is loosely modeled after ansi-color-process-output, so pardon any weirdness.

(defun my-filter-shell-output (string)
  (let ((start-marker comint-last-output-start)
        (end-marker (process-mark (get-buffer-process (current-buffer)))))
    (save-excursion
      (goto-char start-marker)
      (while (search-forward "cloud" end-marker t)
        (replace-match "butt")))))

(with-eval-after-load 'shell
  (add-hook 'comint-output-filter-functions 'my-filter-shell-output t))

The API is somewhat murky. A comint output filter function receives a string argument and is expected to modify the buffer. There’s no documentation on how to retrieve the positions of the last output, so I did whatever aforementioned exemplary function does and restrict the search and replace operations to two markers. How could this possibly go wrong? See for yourself in the following test session:

[wasa@box ~]$ echo cloud
echo butt
butt
[wasa@box ~]$ echo butt
butt
[wasa@box ~]$ echo ponies
ponies

Something is definitely wrong here, an extra line is printed if and only if the replacement would have happened. Most curiously, it doesn’t mirror the user input, but has the replacement as well. After debugging this a bit[2] I remembered that long time ago I’ve set comint-process-echoes because M-x shell kept printing the user input after sending it to the shell. Time to gaze into the abyss:

;; Optionally delete echoed input (after checking it).
(when (and comint-process-echoes (not artificial))
  (let ((echo-len (- comint-last-input-end
                     comint-last-input-start)))
    ;; Wait for all input to be echoed:
    (while (and (> (+ comint-last-input-end echo-len)
                   (point-max))
                (accept-process-output proc)
                (zerop
                 (compare-buffer-substrings
                  nil comint-last-input-start
                  (- (point-max) echo-len)
                  ;; Above difference is equivalent to
                  ;; (+ comint-last-input-start
                  ;;    (- (point-max) comint-last-input-end))
                  nil comint-last-input-end (point-max)))))
    (if (and
         (<= (+ comint-last-input-end echo-len)
             (point-max))
         (zerop
          (compare-buffer-substrings
           nil comint-last-input-start comint-last-input-end
           nil comint-last-input-end
           (+ comint-last-input-end echo-len))))
        ;; Certain parts of the text to be deleted may have
        ;; been mistaken for prompts.  We have to prevent
        ;; problems when `comint-prompt-read-only' is non-nil.
        (let ((inhibit-read-only t))
          (delete-region comint-last-input-end
                         (+ comint-last-input-end echo-len))
          (when comint-prompt-read-only
            (save-excursion
              (goto-char comint-last-input-end)
              (comint-update-fence)))))))

Echoes are canceled by adhering to the following procedure:

  • Waiting for process output until enough characters have been emitted
  • Comparing the emitted text with the last user input
  • Only if they match that echoed text is deleted
  • A hack is applied to not delete the prompt

Unfortunately my output filter is run before that, so it makes the last check fail. I can only wonder whether it’s even possible to use this API meaningfully and whether it will involve breaking changes. Yet everyone and their dog keep proclaiming loudly how great Emacs and its approach to text processing are…

[1]term.el is out because it doesn’t offer anything that deserves to be called an API, eshell.el doesn’t even have documentation and is huge, shell.el is small and simple.
[2]I recommend adding a (sit-for 1) between functions doing buffer manipulation to visualize what’s going on in the buffer. Note that edebug supports doing this for everything by switching to edebug-trace-mode.
-1:-- comint-process-echoes (Post Vasilij Schneidermann)--L0--C0--April 23, 2019 08:09 PM
Some newer versions of watch now support color. For example watch --color ls -ahl --color. https://stackoverflow.com/questions/3793126/colors-with-unix-command-watch
-1:--  (Post sness (noreply@blogger.com))--L0--C0--April 19, 2019 01:44 PM

Emacs Notes: How I shortlist add-ons for my Emacs: Introducing `tablist`

In this article , you will learn about package tablist 1. What is tablist? tablist describes itself as an Extended tabulated-list-mode This package adds marks and filters to tabulated-list-mode. It also puts a dired face on tabulated list buffers. It can be used by deriving from tablist-mode, or with more limited features by enabling tablist-minor-mode … Continue reading How I shortlist add-ons for my Emacs: Introducing `tablist`
-1:-- How I shortlist add-ons for my Emacs:  Introducing `tablist` (Post Emacks)--L0--C0--April 16, 2019 10:28 AM

Timo Geusch: Wrapping up the Emacs on Mac OS X saga

In a previous post I mentioned that I upgraded my homebrew install of Emacs after Emacs 26.2 was released, and noticed that I had lost its GUI functionality. That’s a pretty serious restriction for me as I usually end up Read More

The post Wrapping up the Emacs on Mac OS X saga appeared first on The Lone C++ Coder's Blog.

-1:-- Wrapping up the Emacs on Mac OS X saga (Post Timo Geusch)--L0--C0--April 14, 2019 02:15 PM

Timo Geusch: Emacs 26.2 on WSL with working X-Windows UI

I’ve blogged about building Emacs 26 on WSL before. The text mode version of my WSL build always worked for me out of the box, but the last time I tried running an X-Windows version, I ran into rendering issues.  Read More

The post Emacs 26.2 on WSL with working X-Windows UI appeared first on The Lone C++ Coder's Blog.

-1:-- Emacs 26.2 on WSL with working X-Windows UI (Post Timo Geusch)--L0--C0--April 13, 2019 03:00 AM

Ben Simon: The Embarrassingly Simple Source for An Up To Date Windows Version of emacs

I recently replaced my no-name mini PC with a might-as-well-be-no-name Kingdel NC860 mini PC. These fanless desktop computers have a great form factor, dual monitor support, plenty of USB ports and a bare-bones feel that I love. Credit goes to Coding Horror for inspiring my first purchase of this type of device.

I've recently switched from Firefox to Chrome as my primary browser of choice, and 1password as my password manager. The result: installing Chrome and logging in using both my Work and Personal e-mail meant that my web-based life was essentially setup. Installing Cygwin, Gimp and AutoHotKey meant that I had a nearly complete dev environment. All that was left to do was to install emacs.

At this point, I usually Google around to find the latest version of Windows friendly emacs, often ending up on this sourceforge site. On a whim, however, I thought I'd try something different: I installed emacs via cygwin.

My expectation was that I'd get a console only emacs. And my assumption was totally wrong. I ended up with the same Windows friendly emacs I'm used to, except a whole slew of issues had been resolved. I'm used to emacs operating in terms of Windows drive paths, while cygwin works in terms of a unix'y path mapping. By using a cygwin based emacs, the two environments are now in sync.

A number of issues with eshell were magically fixed, too. #! detection and signal handling (hitting Control-c) in eshell wasn't reliable in my old Windows emacs setup, whereas it's working well under cygwin based emacs.

Finally, the cygwin version of emacs is as up to date as the GNU site offers: version 26.1.

Why didn't I try this years ago?

It blows my mind that I can go from new PC to working dev environment in 15 minutes and zero dollars spent on software.

-1:-- The Embarrassingly Simple Source for An Up To Date Windows Version of emacs (Post Ben Simon (noreply@blogger.com))--L0--C0--April 12, 2019 03:58 PM

Manuel Uberti: Digital minimalism

I reached a point in my life where it’s necessary to rethink my digital habits. It happened before, of course, but in some way or another I’ve never done something useful to actively tackle my tech-addictions.

In my defence, a smartphone entered my life only by way of a birthday present in 2016. I had resisted until then for two reasons: I spend most of the day in front of a screen already, and sociability is not my strongest skill. Three years later, I am still far from being a smartphone enthusiast. Besides occasional phone calls, I seldom check it during the day. I keep messaging at a bare minimum, and there are only a couple of applications nudging me with notifications.

Therefore, the smartphone is not to blame for my compulsively click-driven life. The big giants like Facebook and Twitter don’t matter either, because I stopped using them a long while ago. The problem is everything else. Aggregating RSS feeds seemed like the right move at the beginning, but checking them everyday has turned out to be a time-consuming experience much like browsing news websites to keep up to date. Reddit lures me in constantly, even though the small percentage of valuable content just reminds me of Twitter. GitHub usually offers more click-worthy updates, but the repositories I deem interesting are far less than the uninteresting ones. Letterboxd, a staple of my cinema obsession, may be the worse in this regard; its Activity tab is the drug I can’t resist, and yet I usually find no more than a couple of beautiful reviews a week.

All these considerations are the outcome of reading Digital Minimalism by Cal Newport. Newport’s writing style is at times too pedantic and close to spoon-feeding, but his book highlights potentially effective solutions to escape the miring web of my networking routines. The decluttering process Newport suggests is a difficult task. Depending on the depth of your online addiction, it requires several levels of confidence and willpower, because you know that fighting your own vices is a painful endeavour.

I experienced something similar when I left Twitter behind. I had always valued Twitter more for the network of like-minded people than the chance to share how I feel in a precise moment, and so Twitter had become my go-to reference for film and technology updates. After I deleted my account, I remember asking myself over and over again: am I missing something important? Will I be able to keep up with everyday trends? These questions were always in the back of my head, poking me every time I heard Twitter mentioned somewhere. It took a couple of weeks, maybe three, to realise how much time and peace of mind I gained from a life without Twitter. And I did find the answer to those questions eventually: who cares?

With this precious experience in mind, I treasured Newport’s tips and followed these key steps:

  • cut down my RSS feeds to twenty entries and check them only twice a week
  • remove Reddit from my computer and from my phone
  • remove GitHub from my phone and use it only for work and open source projects
  • access Letterboxd for my writings and check the rest of the community once a week

The trick, as Newport points out, is not just understanding what you value most and whether technology helps you get it or not, but occupying the spare time with something else, possibly unrelated to technology. And so, in my case, it means more time with my wife, longer walks with our dog, more writing, more cooking, and more books. Rewarding leisure, and it’s just the beginning.

Note that I am simplifying Newport’s pages for the sake of brevity, because there is more to his idea of decluttering. Bluntly put, if you are reading this on your phone start looking for Digital Minimalism now.

As daunting as it may look, minimizing our digital consumption is the best way to really and deeply connect with the world around us.

-1:-- Digital minimalism (Post)--L0--C0--April 10, 2019 12:00 AM