emacsair: Many new releases

I am excited to announce new releases of many of my packages.
-1:-- Many new releases (Post)--L0--C0--December 06, 2019 04:00 PM

Sanel Zukan: Handle Chromium & Firefox sessions with org-mode

I was big fan of Session Manager, small addon for Chrome and Chromium that will save all open tabs, assign the name to session and, when is needed, restore it.

Very useful, especially if you are like me, switching between multiple "mind sessions" during the day - research, development or maybe news reading. Or simply, you'd like to remember workflow (and tabs) you had few days ago.

After I decided to ditch all extensions from Chromium except uBlock Origin, it was time to look for alternative. My main goal was it to be browser agnostic and session links had to be stored in text file, so I can enjoy all the goodies of plain text file. What would be better for that than good old org-mode ;)

Long time ago I found this trick: Get the currently open tabs in Google Chrome via the command line and with some elisp sugar and coffee, here is the code:

(require 'cl-lib)

(defun save-chromium-session ()
  "Reads chromium current session and generate org-mode heading with items."
  (interactive)
  (save-excursion
    (let* ((cmd "strings ~/'.config/chromium/Default/Current Session' | 'grep' -E '^https?://' | sort | uniq")
           (ret (shell-command-to-string cmd)))
      (insert
       (concat
        "* "
        (format-time-string "[%Y-%m-%d %H:%M:%S]")
        "\n"
        (mapconcat 'identity
                   (cl-reduce (lambda (lst x)
                                (if (and x (not (string= "" x)))
                                    (cons (concat "  - " x) lst)
                                  lst))
                              (split-string ret "\n")
                              :initial-value (list))
                   "\n"))))))

(defun restore-chromium-session ()
  "Restore session, by openning each link in list with (browse-url).
Make sure to put cursor on date heading that contains list of urls."
  (interactive)
  (save-excursion
    (beginning-of-line)
    (when (looking-at "^\\*")
      (forward-line 1)
      (while (looking-at "^[ ]+-[ ]+\\(http.?+\\)$")
        (let* ((ln (thing-at-point 'line t))
               (ln (replace-regexp-in-string "^[ ]+-[ ]+" "" ln))
               (ln (replace-regexp-in-string "\n" "" ln)))
          (browse-url ln))
        (forward-line 1)))))

So, how does it work?

Evaluate above code, open new org-mode file and call M-x save-chromium-session. It will create something like this:

* [2019-12-04 12:14:02]
  - https://www.reddit.com/r/emacs/comments/...
  - https://www.reddit.com/r/Clojure
  - https://news.ycombinator.com

or whatever urls are running in Chromium instance. To restore it back, put cursor on desired date and run M-x restore-chromium-session. All tabs should be back.

Here is how I use it, with randomly generated data for the purpose of this text:

#+TITLE: Browser sessions

* [2019-12-01 23:15:00]...
* [2019-12-02 18:10:20]...
* [2019-12-03 19:00:12]
  - https://www.reddit.com/r/emacs/comments/...
  - https://www.reddit.com/r/Clojure
  - https://news.ycombinator.com

* [2019-12-04 12:14:02]
  - https://www.reddit.com/r/emacs/comments/...
  - https://www.reddit.com/r/Clojure
  - https://news.ycombinator.com

Note that hack for reading Chromium session isn't perfect: strings will read whatever looks like string and url from binary database and sometimes that will yield small artifacts in urls. But, you can easily edit those and keep session file lean and clean.

To actually open tabs, elisp code will use browse-url and it can be further customized to run Chromium, Firefox or any other browser with browse-url-browser-function variable. Make sure to read documentation for this variable.

Don't forget to put session file in git, mercurial or svn and enjoy the fact that you will never loose your session history again :)

What about Firefox?

If you are using Firefox (recent versions) and would like to pull session urls, here is how to do it.

First, download and compile lz4json, small tool that will decompress Mozilla lz4json format, where Firefox stores session data. Session data (at the time of writing this post) is stored in $HOME/.mozilla/firefox/<unique-name>/sessionstore-backups/recovery.jsonlz4.

If Firefox is not running, recovery.jsonlz4 will not be present, but use previous.jsonlz4 instead.

To extract urls, try this in terminal:

$ lz4jsoncat recovery.jsonlz4 | grep -oP '"(http.+?)"' | sed 's/"//g' | sort | uniq

and update save-chromium-session with:

(defun save-chromium-session ()
  "Reads chromium current session and converts it to org-mode chunk."
  (interactive)
  (save-excursion
    (let* ((path "~/.mozilla/firefox/<unique-name>/sessionstore-backups/recovery.jsonlz4")
           (cmd (concat "lz4jsoncat " path " | grep -oP '\"(http.+?)\"' | sed 's/\"//g' | sort | uniq"))
           (ret (shell-command-to-string cmd)))
...
;; rest of the code is unchanged

Updating documentation strings, function name and any further refactoring is left for exercise.

-1:-- Handle Chromium &amp; Firefox sessions with org-mode (Post)--L0--C0--December 03, 2019 11:00 PM

Sanel Zukan: Handle Chromium & Firefox sessions with org-mode

I was big fan of Session Manager, small addon for Chrome and Chromium that will save all open tabs, assign the name to session and, when is needed, restore it.

Very useful, especially if you are like me, switching between multiple "mind sessions" during the day - research, development or maybe news reading. Or simply, you'd like to remember workflow (and tabs) you had few days ago.

After I decided to ditch all extensions from Chromium except uBlock Origin, it was time to look for alternative. My main goal was it to be browser agnostic and session links had to be stored in text file, so I can enjoy all the goodies of plain text file. What would be better for that than good old org-mode ;)

Long time ago I found this trick: Get the currently open tabs in Google Chrome via the command line and with some elisp sugar and coffee, here is the code:

(require 'cl-lib)

(defun save-chromium-session ()
  "Reads chromium current session and generate org-mode heading with items."
  (interactive)
  (save-excursion
    (let* ((cmd "strings ~/'.config/chromium/Default/Current Session' | 'grep' -E '^https?://' | sort | uniq")
           (ret (shell-command-to-string cmd)))
      (insert
       (concat
        "* "
        (format-time-string "[%Y-%m-%d %H:%M:%S]")
        "\n"
        (mapconcat 'identity
                   (cl-reduce (lambda (lst x)
                                (if (and x (not (string= "" x)))
                                    (cons (concat "  - " x) lst)
                                  lst))
                              (split-string ret "\n")
                              :initial-value (list))
                   "\n"))))))

(defun restore-chromium-session ()
  "Restore session, by openning each link in list with (browse-url).
Make sure to put cursor on date heading that contains list of urls."
  (interactive)
  (save-excursion
    (beginning-of-line)
    (when (looking-at "^\\*")
      (forward-line 1)
      (while (looking-at "^[ ]+-[ ]+\\(http.?+\\)$")
        (let* ((ln (thing-at-point 'line t))
               (ln (replace-regexp-in-string "^[ ]+-[ ]+" "" ln))
               (ln (replace-regexp-in-string "\n" "" ln)))
          (browse-url ln))
        (forward-line 1)))))

So, how does it work?

Evaluate above code, open new org-mode file and call M-x save-chromium-session. It will create something like this:

* [2019-12-04 12:14:02]
  - https://www.reddit.com/r/emacs/comments/...
  - https://www.reddit.com/r/Clojure
  - https://news.ycombinator.com

or whatever urls are running in Chromium instance. To restore it back, put cursor on desired date and run M-x restore-chromium-session. All tabs should be back.

Here is how I use it, with randomly generated data for the purpose of this text:

#+TITLE: Browser sessions

* [2019-12-01 23:15:00]...
* [2019-12-02 18:10:20]...
* [2019-12-03 19:00:12]
  - https://www.reddit.com/r/emacs/comments/...
  - https://www.reddit.com/r/Clojure
  - https://news.ycombinator.com

* [2019-12-04 12:14:02]
  - https://www.reddit.com/r/emacs/comments/...
  - https://www.reddit.com/r/Clojure
  - https://news.ycombinator.com

Note that hack for reading Chromium session isn't perfect: strings will read whatever looks like string and url from binary database and sometimes that will yield small artifacts in urls. But, you can easily edit those and keep session file lean and clean.

To actually open tabs, elisp code will use browse-url and it can be further customized to run Chromium, Firefox or any other browser with browse-url-browser-function variable. Make sure to read documentation for this variable.

Don't forget to put session file in git, mercurial or svn and enjoy the fact that you will never loose your session history again :)

What about Firefox?

If you are using Firefox (recent versions) and would like to pull session urls, here is how to do it.

First, download and compile lz4json, small tool that will decompress Mozilla lz4json format, where Firefox stores session data. Session data (at the time of writing this post) is stored in $HOME/.mozilla/firefox/<unique-name>/sessionstore-backups/recovery.jsonlz4.

If Firefox is not running, recovery.jsonlz4 will not be present, but use previous.jsonlz4 instead.

To extract urls, try this in terminal:

$ lz4jsoncat recovery.jsonlz4 | grep -oP '"(http.+?)"' | sed 's/"//g' | sort | uniq

and update save-chromium-session with:

(defun save-chromium-session ()
  "Reads chromium current session and converts it to org-mode chunk."
  (interactive)
  (save-excursion
    (let* ((path "~/.mozilla/firefox/<unique-name>/sessionstore-backups/recovery.jsonlz4")
           (cmd (concat "lz4jsoncat " path " | grep -oP '\"(http.+?)\"' | sed 's/\"//g' | sort | uniq"))
           (ret (shell-command-to-string cmd)))
...
;; rest of the code is unchanged

Updating documentation strings, function name and any further refactoring is left for exercise.

-1:-- Handle Chromium &amp; Firefox sessions with org-mode (Post)--L0--C0--December 03, 2019 11:00 PM

Irreal: An HTML Email Coda

Last week, I wrote about Perry Metzger’s reasons for not using Emacs to read his email. His take on email is something on the order of, “These days, email is HTML. Deal with it.” Many of us would rather not deal with it but Metzger’s point is well taken. An awful lot of email (maybe even most) comes to you as HTML.

Over at the Emacs subreddit, NukedTeas writes that he’s just had his first, “Gee, I wish I were writing this email in Emacs” moment and goes on to say that he’s going to have to figure out how to do that. The comments were of two types. First, there were the supporters who offered advice on how to do that—mostly mu4e or Notmuch along with offlineimap or mbsync to retrieve the mail.

There was another group of commenters, though, typified by kingpatzer who said that “It’s actually impossible to do email in Emacs”. That comes as a shock to the many of us who do just that everyday. Kingpatzer’s real point, of course, is the same as Metzger’s: Emacs doesn’t render HTML emails very well and most of our email is HTML. A surprising number of commenters agreed or made the same point.

I’m more inclined to agree with oantolin who suggests, “Just stop reading email that isn’t plaintext, I doubt anyone will notice”. That’s a bit smart-alecky, perhaps, but it hints at something that might be true: Most email that comes to you as HTML only is probably not worth reading. I’ve certainly found that true. Almost all of it is commercial messages of one sort or another. There are a few exceptions. The ACM, to its everlasting shame, sends its emails in a form that can’t be rendered in plain text and even EWW doesn’t do a great job with them. Of course, when that happens I just type a v and it pops me into the my browser and displays it there. That’s a bit of a pain but only a bit and it’s more than made up for by doing the majority of my email work in Emacs.

The other point worth making is that most non-spam email that comes as HTML has no reason to be HTML. If you’re an Emacs user, one would expect that most of the people you communicate with know that and send plain text. Sadly, that’s not the case. The only real answer is that given by Metzger: fix Emacs so it can render HTML well. That’s not easy, of course, but it’s definitely worthwhile.

-1:-- An HTML Email Coda (Post jcs)--L0--C0--December 03, 2019 04:53 PM

Sacha Chua: 2019-12-02 Emacs news

EmacsConf 2019 videos out! (Reddit) – Videos, Invidio.us, Youtube

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

-1:-- 2019-12-02 Emacs news (Post Sacha Chua)--L0--C0--December 03, 2019 01:13 AM

Irreal: A Vim User Explores Emacs Distributions

Paul Kuruvilla is a recent immigrant to Emacs from Vim. Of course, that’s a familiar story—along with those going in the opposite direction—and wouldn’t be worth commenting on except for Kuruvilla’s take on the three main Emacs “distributions:” Vanilla Emacs, Spacemacs, and Doom Emacs. His observations are interesting because those of us safely ensconced in the Emacs world become blind to the problems that these variations present to a new user.

As a long time Vim user, Kuruvilla decided against abandoning his Vim muscle memory and opted for packages with Vi emulation. He liked the descriptions he found of Spacemacs and decided to give it a go. Standard Spacemacs seemed too bloated and complicated for his needs so he tried Spacemacs-base. The problems began when he tried to add more functionality. It wasn’t as seamless a process as he would have liked so he tried standard Spacemacs instead.

He found standard Spacemacs to be too bloated and significantly slower for some tasks. He also found that it would sometimes freeze in the middle of editing files. That’s not acceptable, of course, so he took a look at Doom Emacs.

Doom is famously targeted specifically at former Vim users and Kuruvilla found that although it required more work to set up, it met his needs better than Spacemacs. He’s now a happy Emacs user in the camp of the Doom adherents.

As many of you know, I was also a long time Vim user but when I came to Emacs more than a decade ago, I decided to embrace Emacs entirely and chose Vanilla Emacs. I haven’t regretted that choice for an instant but I am aware that some Vanilla Emacs users have migrated to Spacemacs, Doom, or one of the Vi emulation modes to deal with repetitive stress issues.

I know some Irreal readers are ardent Spacemacs users and swear by it so I was a bit surprised at Kuruvilla’s problems with it. If you’re a Spacemacs user and have seen to same problems, leave a comment. Or if you’re a Spacemacs user and haven’t seen those problems, also leave a comment. In the mean time, welcome, Mr. Kuruvilla, to the Emacs family.

-1:-- A Vim User Explores Emacs Distributions (Post jcs)--L0--C0--December 02, 2019 05:36 PM

Manuel Uberti: The aesthetics of patching

In describing my move to Helm, I quickly mentioned another package from Thierry Volpiatto: psession. psession is a light session saving mechanism and it comes with built-in integration for Helm among other things, which of course renders it a valuable improvement to my setup. The installation instructions are pretty clear, so there is no need to bother you with obvious code snippets.

Instead, I want to bother you with my obsessive-compulsive disorder. You see, I am fond of how my beloved text editor looks, especially after boot. I disabled every message, toolbar, scrollbar, menu, and buffer Emacs can throw at me on startup, and the theme is applied as late as possible to ensure nothing obstructs my way to another great day of text editing.

What’s “wrong” with psession then? In order to make the previous sessions available, psession loads some compiled files when Emacs starts. This is what I expect it to do, because there would be no point in saving sessions without restoring them. My only “problem” with this behaviour is the file loading itself.

(cl-defun psession--restore-objects-from-directory
    (&optional (dir psession-elisp-objects-default-directory))
  (let ((file-list (directory-files dir t directory-files-no-dot-files-regexp)))
    (cl-loop for file in file-list do (and file (load file)))))

The code is not hard to understand. What constitutes a rude attack at my delicate aesthetic feelings is that (load file) right before the good-looking closing parentheses. Calling load in this manner causes a bunch of messages to “interfere” with a clean Emacs boot: they show up in the echo area during the loading of my init.el and they hurt so bad!1

Let’s examine the documentation of the function load:

load is a function defined in lread.c.

Signature

(load FILE &optional NOERROR NOMESSAGE NOSUFFIX MUST-SUFFIX)

Documentation

Execute a file of Lisp code named FILE.

[…]

Print messages at start and end of loading unless optional third arg NOMESSAGE is non-nil (but force-load-messages overrides that).

[…]

Perfect. Now I just have to hack psession--restore-objects-from-directory and make sure load is called with a non-nil value for NOMESSAGE. Usually when I want to silence a command I rely on inhibit-message. Let’s say I want to silence the activation of helm-adaptive-mode:

(let ((inhibit-message t))
  (helm-adaptive-mode +1))

However, psession--restore-objects-from-directory is sort of a private function, so I need something else to change it according to my plans. There are probably several good ways to patch psession--restore-objects-from-directory, but my go-to package in these situations is Radon Rosborough’s el-patch.

(el-patch-feature psession)
(with-eval-after-load 'psession
  (el-patch-cl-defun psession--restore-objects-from-directory
    (&optional (dir psession-elisp-objects-default-directory))
    (let ((file-list (directory-files dir t directory-files-no-dot-files-regexp)))
      (cl-loop for file in file-list do (and file (load file nil 'nomessage))))))

Only six lines of code to please my sense of aesthetic. Beauty is always within reach when we are dealing with Emacs.

Note that at the moment of this writing, el-patch-cl-defun is on the develop branch of el-patch. See here to know more about this and to laugh at my poor reading skills.

Footnotes

  1. I know this is silly, but I hope the double quotation marks and the light tone make the irony clear enough. The point is having fun at hacking Emacs, not insulting Thierry. 

-1:-- The aesthetics of patching (Post)--L0--C0--December 01, 2019 12:00 AM

Irreal: HTML Email

If you’ve watched Perry Metzger’s Emacs Conference 2019 talk, as I hope you have, you’ll know that Metzger believes that modern Email should be carried as HTML. He wants—needs, he says—to see his colleagues emails exactly as they were written and to let those colleagues see his emails exactly as he has written them. Here’s a quote from one of his slides explaining why he no longer reads emails in Emacs:

Modern email is HTML. I need to see HTML email the way my colleagues see it. I have no choice. It’s not 1992 any more.

I can sympathize. Metzger is a technical guy doing technical work and he can’t afford to have the ideas in his communications with his colleagues mangled by the email presentation layer. Still, I really, really hate HTML emails and I’m not alone. I’m aware that at this point that’s a rearguard reaction but it’s a view held by many, even—or perhaps especially—by those in the technical fields. Metzger’s probably right but I still hate it.

Paul Graham also has a view on the issue:

I didn’t realize it until after I saw his tweet but that’s exactly how I feel. When I see an HTML email with multiple fonts and fancy formatting, I can be pretty certain it’s trash. Perhaps I need to start hanging out with Metzger’s colleagues. Or perhaps I’m just hopelessly reactionary.

-1:-- HTML Email (Post jcs)--L0--C0--November 27, 2019 04:13 PM

emacspeak: Emacspeak 51.0 (AsssistDog) Unleashed!

Announcing Emacspeak 51.0—AssistDog!

1 For Immediate Release:

San Jose, CA, (Nov 27, 2019)


1.1 Emacspeak 51.0 (AssistDog) 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 51.0
(AssistDog) — a powerful audio desktop for leveraging today's evolving
Data, Social and Assistant-Oriented Internet cloud.


Bigger and more powerful than any smart assistAnt, AssistDog provides
instant access to the most relevant information at all times.


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
November 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 EWW support 🕸
  5. Speech-enables nov.el for a second means of reading EPubs 🕮
  6. Speech-enables module deadgrep
  7. Speech-Enables Emacs Tabs found in emacs 27 ˆ


— 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:

  • Gigger and more powerful than any smart assistAnt, AssistDog provides

instant access to the most relevant information at all times.

  • Emacspeak 50.0 (SageDog) embraces the wisdom of stability as
    opposed to rapid change and the concomitant creation of bugs.🚭: Naturally Intelligent (NI)™ at how information is spoken, Emacspeak

is entirely free of Artificial Ingredients (AI)™.

  • 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 51.0 (AsssistDog) Unleashed! (Post T. V. Raman (noreply@blogger.com))--L0--C0--November 26, 2019 06:32 PM

Irreal: Perry Metzger: The Editor for the Next 40 Years

The videos from the Emacs Conference 2019 are up at YouTube. As many of you know I’m a big fan of Perry Metzger’s 2014 talk on 31 years as an Emacs user so the first video I watched was what amounted to a follow up to that talk. In Emacs: The Editor for the Next Forty Years, Metzger looks at the future of Emacs, where he thinks it’s going, and what it needs to do to remain the premier editor that it is.

As Metzger says, it’s not 1992 anymore and many of the younger hackers aren’t adopting Emacs so we need to update it to meet modern needs. Of course, as Metzger also notes, Emacs has undergone continuous development and modernization throughout its lifetime. The question then—and the theme of the talk—is what changes do we need to make to Emacs? Much of what he has to say will probably ruffle some feathers or at least be controversial but whether you agree or not his arguments are well-formed and I found them cogent.

One of Metzger’s major points is that whatever we do, it must be done incrementally. One of the problems that every proposal for significant rewrites of Emacs has to face is the fact of the huge amount of existing code written for the Emacs ecosystem (Org-mode alone is 120K lines of code). That implies, for example, that implementing a new extension language means that it must interoperate seamlessly with Elisp and use the same run-time system.

Metzger’s summary at the end of the talk lists what he thinks the most important issues are:

  • HTML rendering
  • LSP support built into Emacs
  • Modern email and PIM support
  • A safe concurrency model
  • A new extension language

The body of the talk builds the case for each of these changes and discusses how they might be achieved.

In a second video, Metzger takes questions on the talk. The questions are also worthwhile and expand on the talk. The two videos are 58 minutes and 23 minutes long so you’ll definitely need to set some time aside but if you care about Emacs this is an essential talk. The slides from the talk are also available.

-1:-- Perry Metzger: The Editor for the Next 40 Years (Post jcs)--L0--C0--November 26, 2019 05:04 PM

Irreal: Scimax and Reproducibility

The College of Engineering at Carnegie Mellon has an interesting article on their Web site about John Kitchin and his work on Scimax. I’ve written about Scimax several times (1, 2, 3, 4, 5, 6, 7) so longtime Irreal readers will be familiar with it. If you’re new to Scimax, it’s a package of Emacs applications to make writing scientific papers easier and, in particular, to enable reproducible research: Here’s Kitchin’s Web page on the package.

The CMU article mentions several of Irreal’s favorite topics: Emacs, Org-mode, Writing with Emacs, and reproducible research. In the article, Kitchin makes the point that if your research can’t be verified, no one can tell if it’s the truth or not. Without reproducibility, anyone can say anything and you have to take them at their word. Kitchin says that the point of Scimax is not just to make writing papers easier but to increase the level of research integrity by making its results replicable.

-1:-- Scimax and Reproducibility (Post jcs)--L0--C0--November 25, 2019 04:47 PM

Sacha Chua: 2019-11-25 Emacs news

EmacsConf 2019 videos now out! (Reddit) – Videos, Invidio.us, Youtube

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

-1:-- 2019-11-25 Emacs news (Post Sacha Chua)--L0--C0--November 25, 2019 04:31 PM

Chen Bin (redguardtoo): Yin and Yang in Emacs

As a Chinese, I studied Tao Te Ching since childhood. So I believe Tao (the way) exist in Emacs. Tao is basically Yin and Yang who lives in harmony in Emacs.

I can't say Yin is good and Yang is evil, or vice versa. All I can do is to find the way to make Yin and Yang co-exist.

For example, a few days ago I published Effective "git blame" in Emacs which introduced my package vc-msg.

It became one of my most popular reddit post because its unique feature partial line blame,

vc-msg-good.png

vc-msg-bad.png

I noticed some comments compared my package with Magit. Those comments were very educational and I did learn a few useful tricks.

My point is, vc-msg and Magit could collaborate without any problem, like Yin and Yang lives harmony. If you find any conflict between vc-msg and Magit, just let me know. I will fix it.

I totally understand there are many Magit lovers in Emacs community. So I make vs-msg v1.0.2 to support Magit. You can use partial line blame in vc-msg but calling Magit command to open the commit.

It's only one line setup,

(setq vc-msg-git-show-commit-function 'magit-show-commit)

vc-msg-and-magit.png

I tested in magit-blame-mode and found no issue.

I'm sure vc-msg should work in other major modes or minor modes. There are also two callback functions vc-msg-get-current-file-function and vc-msg-get-line-num-function which users can customize.

-1:-- Yin and Yang in Emacs (Post Chen Bin)--L0--C0--November 25, 2019 08:09 AM

Grant Rettke: Ever Heard Of An Integrated Writing Environment (IWE)?

Ever heard of an integrated writing environment? Me neither. Here is the WikiPedia entry. Org mode is an IWE—right?
-1:-- Ever Heard Of An Integrated Writing Environment (IWE)? (Post grant)--L0--C0--November 24, 2019 06:21 PM

Irreal: Emacs 27.1 Coming

Eli Zaretskii has issued what amounts to a last call for new features to appear in Emacs 27.1. He’s planning to create an Emacs-27 release branch in about a week. After that, only bug fixes for the release will be accepted.

There’s still a lot of testing and release candidates to be done, of course, but we’re getting close.

-1:-- Emacs 27.1 Coming (Post jcs)--L0--C0--November 24, 2019 04:14 PM

Phil Hagelberg: in which we get socially rendered

I joined the fediverse in early 2017. If you haven't heard of it, it's a distributed network providing social media type features without any one centralized authority. Users are in control of their data, and anyone can run their own servers with their own rules, including the ability to block all traffic from other servers if they tolerate abusive behavior, etc.

my profile

It took me a while to get to the point where I was comfortable on the Fediverse. I created an account on the oddly-named icosahedron.website in April, but it didn't stick immediately. It didn't feel like there was much going on because I hadn't found that many users to follow. After a few months of poking my head around, clicking around a bit, and then forgetting about it for another few weeks, I finally got enough momentum for it to be a compelling place for me, and by November I stopped using my Twitter account altogether. I had felt since the 2016 US election that Twitter had spiraled into a worse and worse condition; the site felt engineered to drive more and more "engagement" at the expense of human misery. So making a clean break dramatically improved my mental well-being.

Even tho it makes a few things more complicated (like finding new users to follow[1]), I deeply appreciate the emphasis on user empowerment that's inherent in the design of the fediverse. One of the cornerstones of this empowerment is the ability to run your own fediverse server, or instance. The most common fediverse server software is Mastodon, which could be considered the flagship of the fediverse. While it's very slick and full-featured, a big downside of Mastodon is that it's difficult to run your own server. Administering it requires running a Ruby on Rails application with Node.js, Postgres, Redis, Nginx, ElasticSearch, and more. For servers which serve a medium-to-large community, this overhead can be justifiable, but it requires a lot of mental energy to get started. There are a lot of places where things could go wrong.

The Pleroma project aims to reduce this by creating a dramatically simpler fediverse server. Running a Pleroma server requires just an Elixir application, a Postgres database, and Nginx to handle TLS. Since Elixir is a lot more efficient than Ruby, it's even possible to run it on a low-powered machine like a Raspberry Pi[2]. I set up my own Pleroma server a few weeks ago at hi.technomancy.us. It's running on the Pi in the photo.

a raspberry pi and hard drive

One downside of Pleroma being simpler is that it's really just an API server. All your interaction in the browser goes thru a separate Javascript application called pleroma-fe, and mobile clients like Tusky just hit the JSON API. The API-first design makes sense when you're using the application to browse, post, search, etc, but a big downside is that when you want to share a post with someone else, they have to load all of pleroma-fe just to see it. If you share it with someone who has scripting turned off, then they'll just see a blank white page, which is very unfriendly[3].

I wanted to start using Pleroma, but I wasn't comfortable with this unfriendly behavior. I wanted it so that if I sent a link to a post to a friend, the server would send them the HTML of the post![4] So I took a course of action I never could have taken with a centralized, commercial social network: I fixed it myself. I found that there had been an attempt to start this 8 months ago which had more or less been forgotten, so I used that as my starting point.

Pleroma is written in Elixir, which I had never used before, but I had learned Erlang a few years ago, and many of the core concepts are the same. Since I based my work on the old initial sketch, I was able to make quick progress and add several features, like threading, media, content warnings, and more. I got some really helpful review about how to improve it and test it, and it got merged a couple weeks ago. So now you can see it in action. I'm thankful to the Pleroma developers for their helpful and welcoming attitude.

pleroma screenshot

One of the reasons this is important to me is that I normally use a laptop that's a bit old. But I think it's important for software developers to keep some empathy for users who don't have the latest and greatest hardware. On my laptop, using the pleroma-fe Javascript application to view a post takes eight seconds[5] if you haven't already loaded pleroma-fe (which is the main use case for when you're sharing a link with a friend). If you have it loaded already, it's still 2-3 seconds to load in pleroma-fe. When you have the server generate the HTML, it takes between 200 and 500 milliseconds. But 500ms is nearly a worst-case scenario since it's running on a tiny Raspberry Pi server; on a high-end server it would likely be several times faster.

Running your own fediverse server is still much harder than it should be. I've glossed over the annoyances of Dynamic DNS, port forwarding, and TLS certificates. There's still a lot of opportunity for this to become better. I have a vision of a system where you could sign up for a fediverse server and it would pre-generate an SD card image with Pleroma, Postgres, and Nginx preinstalled and configured with the domain name of your choice, but right now shortcomings in typical consumer-grade routers and consumer ISPs make this impractical. But it's come a long way, and I think it's only going to get better going forward.

If you're interested in running your own fediverse server, you might find runyourown.social helpful, tho it focuses on Mastodon instead of Pleroma. If you're not interested in running your own server, check out instances.social for a listing of servers with open registration. There's never been a better time to ditch corporate social media and join the fediverse!


[1] When people get started on the Fediverse, the first question is just "which server should I choose?" As someone who's been around a while, it's tempting for me to say "it doesn't matter as long as you pick a place with a code of conduct that disallows abusive behavior; all the servers talk to each other, so you can follow any user from any server that hasn't de-federated yours." The problem is this isn't quite true due to the bootstrapping problem; when you're trying to find interesting people to follow, you'll have an easier time if you land on a server where people have interests that overlap with yours.

In a distributed system, one server can't know about every single user in the entire network; it's just too big. So server A only knows about users on server B if someone from server A has already made a connection with a user on server B. Once you choose an server, your view of the network will be determined by the sum total of those followed by your server-mates.

[2] Just don't make the same mistake I did and try to run Postgres on an SD card! I tried this initially, and after a few days I started seeing unexplained segmentation fault loops from Postgres. Apparently this is common behavior when a disk failure corrupts the DB's files. Moving everything over to an external USB drive made the problem go away, but it was certainly a surprise. Everything else can run on the SD card but the database.

[3] Note that this problem also occurs with Twitter. Mastodon is slightly better, but it still refuses to show you images or content-warnings without scripting.

[4] You used to be able to take this very basic behavior for granted, but since the arrival of the "single-page app", it has become some kind of ancient forgotten wisdom.

[5] Eight seconds sounds like a very slow application (and it is!) but it's hardly the worst offender for single-page applications. Trello takes 10 seconds, Jira takes 16 seconds, and Slack takes 18 seconds.

-1:-- in which we get socially rendered (Post Phil Hagelberg)--L0--C0--November 24, 2019 02:42 PM

Alvaro Ramirez: Wizard zines comics in Emacs eshell

24 November 2019 Wizard zines comics in Emacs eshell

Over at wizardzines.com, Julia Evans authors wonderful zines on topics like git, networking, linux, command-line utilities, and others. Some zines are paid. Some are free. No affiliation here, just a fan.

A little while ago, Julia tweeted about a utility she's building to view her original comics on similar topics. I instantly thought it'd be a fun tool to implement for Emacs eshell.

Since then, I subscribed to wizardzines.com/saturday-comics and received a few comics (awk, tar, and bash tricks). I saved them locally (using topic name and dropping file extensions).

ls -1 ~/Downloads/wizardzines-comics/
awk
bash
tar

By no means battle-tested, but here's an elisp snippet defining the ecomic command. It displays inlined comics in the handy eshell.

( require ' eshell)
( require ' iimage)

( defvar  wizardzines-comics-path  "~/Downloads/wizardzines-comics")

( defun  eshell/ecomic ( &rest args)
   "Display command comic in ARGS.
 Note: ensure comic images live in ` wizardzines-comics-path ', named with
 command name and no extension."
  (eshell-eval-using-options
    "ecomic" args
   '((?h  "help" nil nil  "show this usage screen")
      :external  "ecomic"
      :show-usage
      :usage  "COMMAND

 Show COMMAND comic from Julia Evans' https://wizardzines.com/saturday-comics")
   ( let* ((command (nth 0 (eshell-stringify-list (eshell-flatten-list args))))
          (image-fpath (concat (file-name-as-directory
                                (expand-file-name wizardzines-comics-path))
                               command)))
     ( unless (file-exists-p image-fpath)
       ( error  "comic: \"%s\" not found :-(" command))
     (eshell-buffered-print  "\n")
     (add-text-properties 0 (length image-fpath)
                          `(display ,(create-image image-fpath)
                                    modification-hooks
                                    (iimage-modification-hook))
                          image-fpath)
     (eshell-buffered-print image-fpath)
     (eshell-flush))))

ecomic.gif

comments on twitter

Updates

  • Tweaked title.
-1:-- Wizard zines comics in Emacs eshell (Post Álvaro Ramírez)--L0--C0--November 24, 2019 12:00 AM

Irreal: Chris Wellons on PRNGs

I’ve long been an admirer of Chris Wellons’ work and have written about him many times. I almost always learn something new and useful from his blog posts so of course I take notice when he publishes something new. His latest post is about building a linear congruential pseudo-random number generator. If you know anything at all about linear congruential PRNGs you might wonder what there is to say. Quite a bit, it turns out. Although they are very simple—just the recurrence relation \(x_{n+1} = x_{n} × C + A \bmod M\) where \(x_{0}\) is the seed—properly choosing the values of \(C\), \(A\), and \(M\) is important.

A good strategy is to choose prime numbers with certain properties for \(A\) and \(C\) and Wellons shows how easy this is to do using the excellent Calc utility built into Emacs. One of the things I learned from the post was that Calc has a function for the Miller–Rabin primality test. That’s not on the Calc Cheat Sheet so I’d long since forgotten about it and always cranked up my own Scheme version when I needed to check for the primality of large numbers. Having it available in Calc is a big win, especially since I’m probably making the calculations in Calc anyway.

Like all of Wellons’ posts this one is interesting and instructive and definitely worth your time.

-1:-- Chris Wellons on PRNGs (Post jcs)--L0--C0--November 22, 2019 05:02 PM

Alvaro Ramirez: Emacs counsel default search switches

21 November 2019 Emacs counsel default search switches

Following up from Enhanced Emacs searching with counsel switches, rather than remembering silver searcher and ripgrep switches, we can use counsel's ivy-initial-inputs-alist to set these up as default visible switches.

( push '(counsel-ag .  "--file-search-regex '' -- ") ivy-initial-inputs-alist)
( push '(counsel-rg .  "--glob '**' -- ") ivy-initial-inputs-alist)

The default switches stay out of the way in typical searches, but can be easily modified to include (or exclude) results matching specific file names.

default-switches.gif

comments on twitter

-1:-- Emacs counsel default search switches (Post Álvaro Ramírez)--L0--C0--November 21, 2019 12:00 AM

Chen Bin (redguardtoo): Effective "git blame" in Emacs

I published Emacs package vc-msg. It uses git-blame to show commit information of current line.

In the new version, it can display the correct commit information of current line.

For example, the line 6 at https://github.com/redguardtoo/test-git-blame/blob/master/hello.js is changed by three commits.

Select the partial of line 6 and run vc-msg-show, the correct commit is displayed.

Screenshots,

vc-msg-neutral.png

vc-msg-good.png

vc-msg-bad.png

-1:-- Effective "git blame" in Emacs (Post Chen Bin)--L0--C0--November 20, 2019 01:42 PM

Irreal: Zamansky 62: Magit Forge

Mike Zamansky has posted another great video in his Using Emacs Series. This video takes a look at Magit Forge. It’s available from Melpa and is easy to install. Zamansky shows how easy in the video.

Once installed, it just becomes part of the Magit status panel. From there you can make and respond to GitHub—or other Git Forges, such as GitLab—pull requests from the comfort of Emacs. Zamansky demonstrates making and responding to the PR from Emacs and from GitHub. The only thing he couldn’t do from Emacs was to merge code from the PR into the Master branch.

The video is just shy of 18 minutes so you’ll need to schedule some time but it’s definitely worth a few minutes to watch the video.

UPDATE [2019-11-19 Tue 20:50]: Tarsius provides a pointer to a reddit post on why there is no dedicated merge-pull-request.

-1:-- Zamansky 62: Magit Forge (Post jcs)--L0--C0--November 19, 2019 07:54 PM

Mike Zamansky: Using Emacs 62 Magit Forge

Ever since I started looking at Magit as a "git dashboard" instead of as a "git interface" it's been yet another Emacs killer app to me. I just recently started playing with forge which allows Magit to interface and interact with git "forges" like GitHub. This allows you to work on issues and pull requests without ever leaving Emacs. Here's a video on how easy it is. The video doesn't show this but the first time you fire forge up it will prompt you for credentials.
-1:-- Using Emacs 62 Magit Forge (Post)--L0--C0--November 19, 2019 04:25 PM

Chris Wellons: On-the-fly Linear Congruential Generator Using Emacs Calc

I regularly make throwaway “projects” and do a surprising amount of programming in /tmp. For Emacs Lisp, the equivalent is the *scratch* buffer. These are places where I can make a mess, and the mess usually gets cleaned up before it becomes a problem. A lot of my established projects (ex.) start out in volatile storage and only graduate to more permanent storage once the concept has proven itself.

Throughout my whole career, this sort of throwaway experimentation has been an important part of my personal growth, and I try to encourage it in others. Even if the idea I’m trying doesn’t pan out, I usually learn something new, and occasionally it translates into an article here.

I also enjoy small programming challenges. One of the most abused tools in my mental toolbox is the Monte Carlo method, and I readily apply it to solve toy problems. Even beyond this, random number generators are frequently a useful tool (1, 2), so I find myself reaching for one all the time.

Virtually every programming language comes with a pseudo-random number generation function or library. Unfortunately the language standard PRNG often not ideal for my purposes. It’s probably not high quality, slower than it needs to be (also), lacks reliable semantics or behavior between implementations, or is missing some other property I want. So I’ve long been a fan of BYOPRNG: Bring Your Own Pseudo-random Number Generator. Just embed a generator with the desired properties directly into the program. The best non-cryptographic PRNGs today are tiny and exceptionally friendly to embedding. Though, depending on what you’re doing, you might need to be creative about seeding.

Crafting a PRNG

On occasion I don’t have an established, embeddable PRNG in reach, and I have yet to commit xoshiro256** to memory. Or maybe I want to use a totally unique PRNG for a particular project. In these cases I make one up. With just a bit of know-how it’s not too difficult.

Probably the easiest decent PRNG to code from scratch is the venerable Linear Congruential Generator (LCG). It’s a simple recurrence relation:

x[1] = (x[0] * A + C) % M

That’s trivial to remember once you know the details. You only need to choose appropriate values for A, C, and M. Done correctly, it will be a full-period generator — a generator that visits a permutation of each of the numbers between 0 and M - 1. The seed — the value of x[0] — is chooses a starting position in this (looping) permutation.

M has a natural, obvious choice: a power of two matching the range of operands, such as 2^32 or 2^64. With this the modulo operation is free as a natural side effect of the computer architecture.

Choosing C also isn’t difficult. It must be co-prime with M, and since M is a power of two, any odd number is valid. Even 1. In theory choosing a small value like 1 is faster since the compiler won’t need to embed a large integer in the code, but this difference doesn’t show up in any micro-benchmarks I tried. If you want a cool, unique generator, then choose a large random integer. More on that below.

The tricky value is A, and getting it right is the linchpin of the whole LCG. It must be coprime with M (i.e. not even), and, for a full-period generator, A-1 must be divisible by four. For better results, A-1 should not be divisible by 8. A good choice is a prime number that satisfies these properties.

If your operands are 64-bit integers, or larger, how are you going to generate a prime number?

Primes from Emacs Calc

Emacs Calc can solve this problem. I’ve noted before how featureful it is. It has arbitrary precision, random number generation, and primality testing. It’s everything we need to choose A. (In fact, this is nearly identical to the process I used to implement RSA.) For this example I’m going to generate a 64-bit LCG for the C programming language, but it’s easy to use whatever width you like and mostly whatever language you like. If you wanted a minimal standard 128-bit LCG, this will still work.

Start by opening up Calc with M-x calc, then:

  1. Push 2 on the stack
  2. Push 64 on the stack
  3. Press ^, computing 2^64 and pushing it on the stack
  4. Press k r to generate a random number in this range
  5. Press d r 16 to switch to hexadecimal display
  6. Press k n to find the next prime following the random value
  7. Repeat step 6 until you get a number that ends with 5 or D
  8. Press k p a few times to avoid false positives.

What’s left on the stack is your A! If you want a random value for C, you can follow a similar process. Heck, make it prime, too!

The reason for using hexadecimal (step 5) and looking for 5 or D (step 7) is that such numbers satisfy both of the important properties for A-1.

Calc doesn’t try to factor your random integer. Instead it uses the Miller–Rabin primality test, a probabilistic test that, itself, requires random numbers. It has false positives but no false negatives. The false positives can be mitigated by repeating the test multiple times, hence step 8.

Trying this all out right now, I got this implementation (in C):

uint64_t lcg1(void)
{
    static uint64_t s = 0;
    s = s*UINT64_C(0x7c3c3267d015ceb5) + UINT64_C(0x24bd2d95276253a9);
    return s;
}

However, we can still do a little better. Outputting the entire state doesn’t have great results, so instead it’s better to create a truncated LCG and only return some portion of the most significant bits.

uint32_t lcg2(void)
{
    static uint64_t s = 0;
    s = s*UINT64_C(0x7c3c3267d015ceb5) + UINT64_C(0x24bd2d95276253a9);
    return s >> 32;
}

This won’t quite pass BigCrush in 64-bit form, but the results are pretty reasonable for most purposes.

But we can still do better without needing to remember much more than this.

Appending permutation

A Permuted Congruential Generator (PCG) is really just a truncated LCG with a permutation applied to its output. Like LCGs themselves, there are arbitrarily many variations. The “official” implementation has a data-dependent shift, for which I can never remember the details. Fortunately a couple of simple, easy to remember transformations is sufficient. Basically anything I used while prospecting for hash functions. I love xorshifts, so lets add one of those:

uint32_t pcg1(void)
{
    static uint64_t s = 0;
    s = s*UINT64_C(0x7c3c3267d015ceb5) + UINT64_C(0x24bd2d95276253a9);
    uint32_t r = s >> 32;
    r ^= r >> 16;
    return r;
}

This is a big improvement, but it still fails one BigCrush test. As they say, when xorshift isn’t enough, use xorshift-multiply! Below I generated a 32-bit prime for the multiply, but any odd integer is a valid permutation.

uint32_t pcg2(void)
{
    static uint64_t s = 0;
    s = s*UINT64_C(0x7c3c3267d015ceb5) + UINT64_C(0x24bd2d95276253a9);
    uint32_t r = s >> 32;
    r ^= r >> 16;
    r *= UINT32_C(0x60857ba9);
    return r;
}

This passes BigCrush, and I can reliably build a new one entirely from scratch using Calc any time I need it.

Bonus: Adapting to other languages

Sometimes it’s not so straightforward to adapt this technique to other languages. For example, JavaScript has limited support for 32-bit integer operations (enough for a poor 32-bit LCG) and no 64-bit integer operations. Though BigInt is now a thing, and should make a great 96- or 128-bit LCG easy to build.

function lcg(seed) {
    let s = BigInt(seed);
    return function() {
        s *= 0xef725caa331524261b9646cdn;
        s += 0x213734f2c0c27c292d814385n;
        s &= 0xffffffffffffffffffffffffn;
        return Number(s >> 64n);
    }
}

Java doesn’t have unsigned integers, so how could you build the above PCG in Java? Easy! First, remember is that Java has two’s complement semantics, including wrap around, and that two’s complement doesn’t care about unsigned or signed for multiplication (or addition, or subtraction). The result is identical. Second, the oft-forgotten >>> operator does an unsigned right shift. With these two tips:

long s = 0;

int pcg2() {
    s = s*0x7c3c3267d015ceb5L + 0x24bd2d95276253a9L;
    int r = (int)(s >>> 32);
    r ^= r >>> 16;
    r *= 0x60857ba9;
    return r;
}

So, in addition to the Calc step list above, you may need to know some of the finer details of your target language.

-1:-- On-the-fly Linear Congruential Generator Using Emacs Calc (Post)--L0--C0--November 19, 2019 01:17 AM

Sacha Chua: 2019-11-18 Emacs news

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

-1:-- 2019-11-18 Emacs news (Post Sacha Chua)--L0--C0--November 18, 2019 04:34 PM

Irreal: Generating Technical Documents with Org-mode

Mike Hamrick has put up an excellent video on using Emacs and Org-mode to publish nice looking and consistent technical documents. In preparing a document, Hamrick uses literate programming and—although he doesn’t mention it—reproducible research techniques. That’s important, because as he notes, if the code or data used in the document changes, things that depend on that code or data will change as well and it’s important to keep them in sync.

This is exactly the problem—or at least one of the problems—that Org-mode’s Babel was designed to solve. By having Babel embed the results of running the document’s code against its data into the document itself, you’re guaranteed that everything will stay consistent.

Hamrick has a few tricks that he uses to get a nice looking document and keep it consistent. For HTML, he uses Fabrice Niessen’s ReadTheOrg theme, which I’ve written about before, to produce beautiful HTML documents. The other trick he uses that I really liked is to have a file of helper functions that he can call from the text he’s writing. These do things like return the length of a string or the first 2 characters of a string. By using them, he ensures that his document remains consistent even if the data the string is from changes.

Don’t worry about trying to absorb the source code from the video. He’s put all the code and data for the video on GitLab. Similarly, his configuration files are on GitLab so you can see his publishing setup.

The video is 22 minutes, 42 seconds long so you’ll need to block out some time but it’s very much worth it. If you use Org-mode in your writing, you really need to watch this video.

-1:-- Generating Technical Documents with Org-mode (Post jcs)--L0--C0--November 17, 2019 06:00 PM

Marcin Borkowski: Diffing buffer fragments, continued

Apparently, my last blog post about diffing buffer fragments sparked a small discussion on Twitter. Most comments fell into one of two categories: some people wanted to use ediff (which I explicitly mentioned I didn’t want), and some people complained about the temp files (which do not bother me that much). Well, it turns out that I really did not have to create the temp files after all!
-1:-- Diffing buffer fragments, continued (Post)--L0--C0--November 17, 2019 10:28 AM

Irreal: Zamansky 61: Org-msg

Mike Zamansky has another video up in his Using Emacs Series. This time he looks at writing mu4e emails in Org-mode. Like me, he mostly wants to send plain text emails but sometimes he’d like to send tables, source code, or other rich text. He tried using the built-in org-mu4e-compose-org-mode but it’s deprecated and didn’t do everything he wanted. I’ve had the same experience. I tried org-mu4e-compose-org-mode but it didn’t do many of the things I cared about so I stopped using it.

Happily, Zamansky has found another solution: org-msg. It does a much better job of allowing you to use Org markup in your emails and rendering the results nicely. Of course, to do that it sends your mail as HTML so if you don’t like that, org-msg is not for you.

Take a look at Zamansky’s video to see both org-mu4e-compose-org-mode and org-msg in action. You can see right away why org-msg is the superior solution. In addition to its better rendering, org-msg is more configurable. You can, for example, set it to automatically add a signature or to extract the sender’s name from an email you’re replying to and use it to add a salutation.

If you’ve been looking for a way to use Org-mode with mu4e, be sure to spend a few minutes to watch this video. The video is just short of 15 minutes so it should be easy to find some time for it.

-1:-- Zamansky 61: Org-msg (Post jcs)--L0--C0--November 16, 2019 05:44 PM

Mike Zamansky: Using Emacs 61 - org-msg

By living in Emacs I get a consistent interface across all sorts of tasks - programming, lesson planning, making presentations, preparing documents, and yes, even email. I've been using mu4e as my Emacs email client for a while now. Currently, I'm using Emacs for my work email and Gmail for personal. I've been thinking of going whole hog to mu4e and possibly migrating from Gmail to a new email provider for the personal stuff but there are still a few pain points with Emacs email:
-1:-- Using Emacs 61 - org-msg (Post)--L0--C0--November 16, 2019 09:00 AM

Manuel Uberti: At the helm of my configuration

It was a cold winter back in December 2014. If memory serves me well, it was time spent at tinkering with old hardware and obscure window managers, reading my first books on functional programming, and dealing with something about text editors I can’t quite put my finger on.

I was also reading about Helm and the praises everywhere in the Emacs community for this package: it can do this, it improves that, it will take you closer to Emacs Nirvana. So yeah, I believed the hype, because it came from trusted sources, especially the Nirvana-guy. Soon Helm took over my configuration and I was using it for everything: switching buffers, selecting bookmarks, in-buffer and per-project searches. Anything involving candidates completion was in the wise hands of Helm.

After a while Ivy came along, and the rest is history. I have been using Ivy/Counsel for such a long a time I might as well say they have become the central drivers of my Emacs setup. Along with the likes of counsel-projectile, these are the packages I use the most during the day.

Lately I’ve been following some conversations about completion-styles, and when I learned that Thierry Volpiatto was working on leveraging Helm for this I just could not resist. Note that Thierry is still devising the implementation, so there is no need to rush at opening issues and scream at him. Anyway, Helm was back in my radar now, and so I took the chance to see if I could come up with a setup which would mirror my everyday workflow with Ivy/Counsel.

I immediately noticed that the theme I use lacked proper support for some Helm faces, but nothing stopped me to do something about it. Much like Ivy/Counsel, Helm provides its own version for common operations such as helm-M-x, helm-find-files, helm-mini, helm-recentf, helm-bookmarks, helm-show-kill-ring, and helm-resume. These are the core features for me, and they work as expected. I also enabled helm-adaptive-mode and helm-autoresize-mode, fixing the Helm window height to my preferences.

As I did with Ivy/Counsel, I made buffer switching (i.e., helm-mini) ignore some files:

(require 'helm-buffers)
(setq helm-ff-skip-boring-files t)
(dolist (regexp '("\\`\\*direnv" "\\`\\*straight" "\\`\\*xref"))
  (cl-pushnew regexp helm-boring-buffer-regexp-list))

My projects are all Git-versioned, hence I installed helm-ls-git, which superseded Projectile and the related helm-projectile in an instant. In order to make per-project lookups with Helm as easy as they were with Ivy/Counsel, I went with helm-ag and helm-xref. To make it even better, I added psession and configured it to persist the things I need from my Emacs sessions. The only goodies I put on top of this setup are helm-bibtex and helm-tramp.

Back in the day, Helm felt heavier and more bloated than Ivy/Counsel, but that is nonsense and was probably due to me being still young and inexperienced at Emacs tweaking. In fact, it still takes less than one second for my Emacs to boot, and so far there is nothing in terms of functionalities I have been missing from my previous configuration. We could argue about UI minimalism and design choices as long as we want, or we could simply try what the Emacs ecosystem offers and decide for ourselves what suits our text editor best.

-1:-- At the helm of my configuration (Post)--L0--C0--November 16, 2019 12:00 AM

Irreal: Generating Gantt Charts with Org-mode

Perhaps because I’ve always worked for smaller organizations, I’ve never had to deal with Gantt charts. I’ve always considered them yet another management fad but that may be due to ignorant prejudice. In any event, lots of people use them and find them useful.

The other day I saw a pointer to a recent video on generating Gantt charts with Org-mode. It turns out to be pretty easy. Once you get the start and end dates into an Org table it’s just a matter of invoking a bit of gnuplot code from a source block to generate the chart.

As I said, I don’t have much interest in Gantt charts but I do like reading about leveraging Org-mode to accomplish tasks that used to take dedicated applications. The video is 13 minutes, 11 seconds so it should be easy to fit it in. It’s worth taking a look at if only to see how versatile Org-mode and Emacs can be.

-1:-- Generating Gantt Charts with Org-mode (Post jcs)--L0--C0--November 15, 2019 04:18 PM

Irreal: Emacs Resources for Writers

Recently, James Gill tweeted about a collection of Emacs resources for writers that he’s curated into a GitHub repository. There are two parts to the collection:

  1. Tips and examples for writing with Emacs, and
  2. Writing a book with Emacs.

As you’d expect, most of the articles are about leveraging Org-mode for writing. That’s no surprise, of course, because Org excels at that. Indeed, almost any type of writing from memos or blog posts—such as Irreal’s—to journal articles or books is easily accomplished with Org. I’ve reached the point were virtually everything I write is done with Org-mode.

Sadly, the literary writing market runs on Word so if that’s your niche, you’re going to have to deal with conversion. Org, of course, has built in tools for that and if those don’t meet your needs, the excellent Pandoc almost certainly will.

If you’re a writer who’d like to escape from the pain that is Word and give Emacs a try, be sure to read the articles in Gill’s list. I’ve discussed several of them in Irreal previously but a few are new to me. A handful of the resources are videos but most are short blog posts or articles that are easy and quick to read.

It’s not always obvious how to use Emacs for writing effectively so the articles and videos collected by Gill, which distill a lot of hard won wisdom, can be a real help.

-1:-- Emacs Resources for Writers (Post jcs)--L0--C0--November 13, 2019 03:55 PM

Chen Bin (redguardtoo): Emacs is the best merge tool for Git

I used to regard vimdiff as the best merge tool for Git because it's simply fast.

Here is the demo how I use vimdiff to resolve conflicts from https://github.com/redguardtoo/test-git-mergetool.

vimdiff-as-git-merge-tool.gif

Please note in the screencast I use Git built in command mergetool. It will automatically open conflicted file one by one using vim. In other software, the developer need manually select and open the conflicted file.

The only issue is Vim is not as powerful as Emacs.

Resolving conflicts is NOT only picking up a diff hunk from either remote buffer or local buffer. I often need place my hunk into merged buffer first, then I go to remote buffer and copy some snippet into merged buffer. So there are lots of sub-window operations.

In Emacs, I use Ace-window and Winum to move focus between sub-windows. I also use API window-configuration-to-register and jump-to-register to save/load windows layout. Besides, Ediff is a beast to handle diff and patch.

So I give one example to prove why Emacs should be a better merge tool in theory. If you are good at both Vim and Emacs, you know it's the truth.

Now let's talk the real world problem. And I will show you a perfect solution soon.

The problem is, I never use Emacs to resolve merge conflicts for two reasons:

  • First, My Emacs configuration uses too many packages. It starts up slowly. As you can see from vimdiff demo, git mergetool restarts the editor many times. So the editor should be lightweight.
  • Second, the UI of ediff is not right. UI of Vimdiff is much better. All operations should be completed freely in any sub-window instead of ediff control panel only.

Luckily, Emacs gives me the full freedom to solve the problem. The final result is beyond my expectation.

Here is the complete solution.

This technique is only useful for git mergetool because git will open and close the text editor Emacs many times.

Insert below code into ~/.gitconfig,

[mergetool.ediff]
# use git mergetool ediff to resolve conflicts
cmd = emacs -nw -Q --eval \"(setq startup-now t)\" -l \"~/.emacs.d/init.el\" --eval \"(progn (setq ediff-quit-hook 'kill-emacs) (if (file-readable-p \\\"$BASE\\\") (ediff-merge-files-with-ancestor \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" nil \\\"$MERGED\\\") (ediff-merge-files \\\"$LOCAL\\\" \\\"$REMOTE\\\" nil \\\"$MERGED\\\")))\"

In above code, option -Q equals -q --no-site-file --no-splash. Actually, only -q is critical. -q means "Do not load an init file". A global emacs lisp flag startup-now is defined before loading ~/.emacs.d/init.el.

Then in ~/.emacs.d/init.el, I need only add one line,

(when (not (boundp 'startup-now))
  ;; heavy weight configuration happens here
  )

When startup-now is defined, all the heavyweight configuration should be off. Considering in this scenario, we are using Emacs only as merge tool, 99% configuration could be turned off. For example, set up for any programming language is not required. Flyspell and flycheck should be off. Yasnippet is also useless.

I only need focus on essential operations related to text/file/window.

Evil should be used. At the beginning of this article, I said "I love vimdiff because it's fast". It's impossible to be more efficient without Evil.

Any patch/diff utilities should be included too. counsel/swiper/ivy is also must have because I can use counsel-git to find file and counsel-git-grep to grep text.

Native Emacs API is enough to save/load windows layout.

Packages dependent on ediff (Magit?) could also benefit from optimization of ediff.

The optimization is simple. Do everything in merged buffer.

First I move focus into merged buffer when Emacs starts up,

This set up happens in ediff-startup-hook,

(defun ediff-startup-hook-setup ()
  ;; hide control panel if it's current buffer
  (when (string-match-p (setq my-ediff-panel-name (buffer-name))
                        "\*Ediff Control Panel.*\*")
    ;; move to the first difference
    (ediff-next-difference)
    ;; move to the merged buffer window
    (winum-select-window-by-number 3)
    ;; save the windows layout
    (window-configuration-to-register ?a)))

(add-hook 'ediff-startup-hook 'ediff-startup-hook-setup)

Please note I use winum-select-window-by-number from winum move focus to merged buffer. You can use any other third party package or native API select-window instead.

Saving initial windows layout into register a is achieved by (window-configuration-to-register ?a) in ediff-startup-hook. (jump-to-register ?a) restores the saved layout.

Then we need make sure ediff commands can be used out of ediff's panel. Currently ediff command can only be triggered inside of its panel.

The trick is "move focus into ediff panel temporarily to execute its commands, then move focus back to original window".

So I designed a macro my-ediff-command to do this,

(defmacro my-ediff-command (cmd &optional no-arg)
  `(lambda (&optional arg)
     (interactive "P")
     (let* ((w (get-buffer-window)))
       ;; go to panel window
       (select-window (get-buffer-window my-ediff-panel-name))
       ;; execute ediff command, ignore any error
       (condition-case e
           (if ,no-arg (funcall ,cmd) (funcall ,cmd arg))
         (error
          (message "%s" (error-message-string e))))
       ;; back to original window
       (select-window w))))

Usage is simple,

(global-set-key (kbd "C-c C-y") (my-ediff-command 'ediff-next-difference))

Here is the list of essential ediff commands,

  • ediff-next-difference
  • ediff-previous-difference
  • ediff-restore-diff-in-merge-buffer
  • ediff-revert-buffers-then-recompute-diffs
  • ediff-copy-A-to-C
  • ediff-copy-A-to-C
  • ediff-copy-both-to-C

You can use Hyra or General.el to assign key bindings.

The definition of ediff-copy-both-to-C,

;; @see https://stackoverflow.com/a/29757750/245363
(defun ediff-copy-both-to-C (&optional arg)
  "Copy code from both A and B to C."
  (interactive)
  (ediff-copy-diff ediff-current-difference nil 'C nil
                   (concat
                    (ediff-get-region-contents ediff-current-difference 'A ediff-control-buffer)
                    (ediff-get-region-contents ediff-current-difference 'B ediff-control-buffer))))

Here is my ~/.gitconfig and my ediff set up in real world.

Please note the techniques introduced here can be used with other VCS (subversion, perforce …).

Demo on using Emacs to resolve merge conflicts,

emacs-as-git-merge-tool.gif

-1:-- Emacs is the best merge tool for Git (Post Chen Bin)--L0--C0--November 13, 2019 01:29 PM

Irreal: Remote Debugging With Tramp

Matt Ray gave a very nice presentation to EmacsConf 2019 on Interactive Remote Debugging and Development with TRAMP Mode. One of the frequent complaints about Emacs is that it’s hard to work with remote files. Mostly that’s because the person complaining doesn’t know about Tramp. There are, of course, some situations where Tramp is not the best solution but it’s usually an excellent way of working with remote files.

It’s easy to think of Tramp simply as a way of editing remote files but it’s actually much more powerful than that. Ray demonstrates some of that power first by using Tramp to open a shell on a remote system and then by showing how he uses it to work with virtual machines on his own workstation. He uses the freely available tools Chef, Vagrant, and Kitchen to spin up a virtual instance of Debian and work with it all from the comfort of Emacs.

Even command-line aficionados will enjoy his video because although he stays in Emacs, he does a lot of the work using the shell command. He begins the video by showing why using the shell from Emacs can be a win over firing up a separate terminal. During the rest of the presentation, he just opens a shell on the remote machine—or virtual machine—when he needs to make a change to the remote environment.

The video is about 35 and half minutes so you’ll probably have to schedule some time but I found it worth the time.

-1:-- Remote Debugging With Tramp (Post jcs)--L0--C0--November 12, 2019 04:08 PM

Marcin Borkowski: Diffing buffer fragments

While working on a certain project, I needed to check the differences between two text fragments. We all know and love diff, but it operates on files, and what I had was two fragments of two files (or sometimes even of one file) which I wanted to compare. There are a few solutions to this problem, but they seemed too complicated for me.
-1:-- Diffing buffer fragments (Post)--L0--C0--November 11, 2019 06:49 PM

Sacha Chua: 2019-11-11 Emacs news

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

-1:-- 2019-11-11 Emacs news (Post Sacha Chua)--L0--C0--November 11, 2019 04:33 PM

Irreal: List Commits to Dired-Marked Files

Via Wilfred Huges we have this useful tip:

Apparently, it’s not widely known.

I just tried it—I’m running dired+—and it worked perfectly. It’s easy to see how the magit-dired-log command could be very useful.

-1:-- List Commits to Dired-Marked Files (Post jcs)--L0--C0--November 11, 2019 04:24 PM

Alex Bennée: dired-rsync 0.5 release

If you’ve been running from MELPA you will have had all these features already but it was certainly overdue a stable tagging. The commit history shows a lot of faffing around getting the CI working again. However there are a bunch of customisation tweaks exposed as well as support for remote-to-remote rsync support (with a very ugly port-forward hack). From the NEWS file:

  • Big CI clean-ups (dropped emake, added Cask)
  • smarter modeline status (show R:n% when one job running)
  • make dired-rsync process dest with expand-file-name
  • we now support remote to remote with an ugly port forward hack
  • prompt the user for a passphrase if we detect stall in process
  • add some basic ert tests
  • new customisation option dired-rsync-source-files
  • new customisation hook dired-rsync-failed-hook

Happy file syncing 😉

-1:-- dired-rsync 0.5 release (Post Alex)--L0--C0--November 10, 2019 07:42 PM

Alvaro Ramirez: Enhanced Emacs searching with counsel switches

10 November 2019 Enhanced Emacs searching with counsel switches

The counsel family of Emacs search commands are great for searching the filesystem. More specifically, counsel-rg, counsel-ag, and counsel-pt, which use the popular ripgrep, silver searcher, and platinum searcher utilities.

counsel-rg is my default searcher. It returns results quickly, with live updates as I tweak the search query.

Up until recently, my queries typically matched text in files only. This works great, but every so often I wished I could amend the query to include (or exclude) results matching specific file names. Turns out, you can prepend the search query with additional switches using the "–" separator.

The switches are usually utility-specific, but if we wanted to keep results from file names matching a glob, we can prepend the ripgrep query with something like "–glob Make* –" or the shorter version "-g Make* –".

rg: -g Make* – install

counsel-rg-switch.gif

-1:-- Enhanced Emacs searching with counsel switches (Post Álvaro Ramírez)--L0--C0--November 10, 2019 12:00 AM

Alvaro Ramirez: Emacs org block company completion

10 November 2019 Emacs org block company completion

Back in 2015, I bound the "<" key to a hydra for quickly inserting org blocks. The idea came from Oleg's post on org-mode block templates in Hydra. The suggested binding settled in my muscle memory without much effort.

Fast forward to Febrary 2019. I replaced the hydra with org-insert-structure-template when org-try-structure-completion was removed from org mode. No biggie, as I kept the same binding to "<" and hardly noticed the change.

Since my primary use-case for easy templates is inserting source blocks, I was keen to expedite choosing the source language as well as inserting the source block itself.

Writing a small company mode completion backend fits my primary use-case pretty well.

company-org-block.gif

The company backend looks as follow ( Warning: Snippet needs Org v9.2):

( require ' map)
( require ' org)
( require ' seq)

( defvar  company-org-block-bol-p t  "If t, detect completion when at
 begining of line, otherwise detect completion anywhere.")

( defvar  company-org--regexp  "< \\ ( [ ^  ]* \\ ) ")

( defun  company-org-block (command  &optional arg  &rest ignored)
   "Complete org babel languages into source blocks."
  ( interactive (list 'interactive))
  ( cl-case command
    ( interactive (company-begin-backend 'company-org-block))
    (prefix ( when (derived-mode-p 'org-mode)
              (company-org-block--grab-symbol-cons)))
    (candidates (company-org-block--candidates arg))
    (post-completion
     (company-org-block--expand arg))))

( defun  company-org-block--candidates (prefix)
   "Return a list of org babel languages matching PREFIX."
  (seq-filter ( lambda (language)
                (string-prefix-p prefix language))
               ;;  Flatten ` org-babel-load-languages ' and
               ;;  ` org-structure-template-alist ', join, and sort.
              (seq-sort
               #'string-lessp
               (append
                (mapcar #'prin1-to-string
                        (map-keys org-babel-load-languages))
                (map-values org-structure-template-alist)))))

( defun  company-org-block--template-p (template)
  (seq-contains (map-values org-structure-template-alist)
                template))

( defun  company-org-block--expand (insertion)
   "Replace INSERTION with actual source block."
  (delete-region (point) (- (point) (1+  ;;  Include "<" in length.
                                     (length insertion))))
  ( if (company-org-block--template-p insertion)
      (company-org-block--wrap-point insertion
                                      ;;  May be multiple words.
                                      ;;  Take the first one.
                                     (nth 0 (split-string insertion)))
    (company-org-block--wrap-point (format  "src %s" insertion)
                                    "src")))

( defun  company-org-block--wrap-point (begin end)
   "Wrap point with block using BEGIN and END.  For example:
 #+begin_BEGIN
   |
 #+end_END"
  (insert (format  "#+begin_%s\n" begin))
  (insert (make-string org-edit-src-content-indentation ?\s))
   ;;  Saving excursion restores point to location inside code block.
  ( save-excursion
    (insert (format  "\n#+end_%s" end))))

( defun  company-org-block--grab-symbol-cons ()
   "Return cons with symbol and t whenever prefix of < is found.
 For example: \" (\"e\" . t)"
  ( when (looking-back ( if company-org-block-bol-p
                          (concat  "^" company-org--regexp)
                        company-org--regexp)
                      (line-beginning-position))
    (cons (match-string-no-properties 1) t)))

To use, add the backend enable company-mode in org-mode:

(add-to-list 'company-backends 'company-org-block)
(company-mode +1)

Updates

-1:-- Emacs org block company completion (Post Álvaro Ramírez)--L0--C0--November 10, 2019 12:00 AM

Irreal: Project and Org Mode

Karl Voit has an interesting post in which he explores ways of defining projects in Org-mode. Note that by “project” Voit doesn’t mean the type of object handled by an app such as Projectile, but a set of tasks meant to achieve a common goal. If you’re like me, the answer seems obvious: add a project tag to the header defining the project.

Of course, things aren’t that simple, especially for someone like Voit who on the one hand has exacting standards for how things should appear in, say, his agenda but on the other hand wants very fluid Org files. By “fluid” I mean that projects aren’t necessarily top level items or even second level items. They can appear anywhere in the tree. I’m inclined to be more rigid in my Org file layout so I avoid some of the problems that Voit has.

Voit discusses several possibilities along with their pros and cons. I’ll let you read his post to see what solution he finally settled on. If you’re trying to impose a project structure on top of Org, it’s definitely worth taking a look at his discussion.

-1:-- Project and Org Mode (Post jcs)--L0--C0--November 09, 2019 03:06 PM