Irreal: Zamansky: Learning Elisp #15

Mike Zamansky has published the latest video in his Learning Elisp series. This is (probably) the last video in his emoji replacement project. In the last video, Zamansky showed how to turn his emoji replacement code into a minor mode. This video cleans things up a bit and explores two other aspects of programming in Elisp.

First off, he shows how configure the minor mode to use either the replace or overlay method for substituting an emoji for a keyword. That’s done with a boolean variable, of course, but rather than use it to test which function to call after every screen update, he uses it to set a function variable that is installed in the appropriate hook.

He mentions, but does not elaborate on, the need to use funcall to actually call the function in the variable. That doesn’t matter here because the variable is used by hook mechanism and not called directly by Zamansky’s code.

The second aspect is how to define the boolean variable. He first considers using devar instead of setq but explains that the proper way of doing it in this instance is with defcustom. Doing it that way allows the user to set the variable using the Emacs Custom interface. That way, the variable can be set once and the values will persist between Emacs invocations but can still be changed whenever the user desires.

Even if you’re familiar with Lisp from, say, Common Lisp or Scheme, the defcustom form will be new and is worth learning about. The video is 11 minutes, 59 seconds so you’ll probably have to schedule some time but as usual with Zamansky’s videos, it will be time well spent.

-1:-- Zamansky: Learning Elisp #15 (Post jcs)--L0--C0--November 30, 2023 04:49 PM

Amit Patel: Emacs and shellcheck

Julia Evans had a great talk called Making Hard Things Easy. One of the takeaways for me was that I should be using tools for parts of a system I find hard to remember. In particular, when writing bash scripts I should be using shellcheck.

It turns out Emacs 29 has support for shellcheck, and older versions of Emacs can use the flymake-shellcheck page.

To set it up in Emacs 29:

(use-package flymake
  :bind (("H-e" . flymake-show-project-diagnostics)))

(use-package sh-script
  :hook (sh-mode . flymake-mode))

I use consult for navigating my errors, and I want to make errors more noticable in the mode line, so my flymake configuration is:

(use-package flymake
  :bind (("H-e" . my/consult-flymake-project))
  :preface
  (defun my/consult-flymake-project ()
    (interactive)
    (consult-flymake t))
  :custom
  (flymake-suppress-zero-counters t)
  :config
  (defface my/flymake-modeline-error-echo
    '((t :inherit 'flymake-error-echo :background "red"))
    "Mode line flymake errors")
  (put 'flymake-error 'mode-line-face 'my/flymake-modeline-error-echo)
  (defface my/flymake-modeline-warning-echo
    '((t :inherit 'flymake-warning-echo :background "orange"))
    "Mode line flymake warnings")
  (put 'flymake-warning 'mode-line-face 'my/flymake-modeline-warning-echo))

It's too early to know what other tweaks I might want, but so far it's alerted me to several errors in my shell scripts.

Update: [2023-10-07] Comments on HN pointed to bash-language-server which works with emacs lsp or eglot.

-1:-- Emacs and shellcheck (Post Amit (noreply@blogger.com))--L0--C0--November 30, 2023 04:31 AM

Alvaro Ramirez: Building your own bookmark launcher

29 November 2023 Building your own bookmark launcher

sponsor✨ this content

I've been toying with the idea of managing browser bookmarks from you know where. Maybe dump a bunch of links into an org file and use that as a quick and dirty bookmark manager. We'll start with a flat list plus fuzzy searching and see how far that gets us.

The org file would look a little something like this:

My bookmarks
- [[https://lobste.rs/t/emacs][Emacs editor (Lobsters)]]
- [[https://emacs.stackexchange.com][Emacs Stack Exchange]]
- [[https://www.reddit.com/r/emacs][Emacs subreddit]]
- [[https://emacs.ch][Emacs.ch (Mastodon)]]
- [[https://www.emacswiki.org][EmacsWiki]]
- [[https://planet.emacslife.com/][Planet Emacslife]]

Next we need fuzzy searching, but first let's write a little elisp to extract all links from the org file:

(require ' org-element)
(require ' seq)

(defun  browser-bookmarks (org-file)
   "Return all links from ORG-FILE."
  (with-temp-buffer
    (let (links)
      (insert-file-contents org-file)
      (org-mode)
      (org-element-map (org-element-parse-buffer) 'link
        (lambda (link)
          (let* ((raw-link (org-element-property  :raw-link link))
                 (content (org-element-contents link))
                 (title (substring-no-properties (or (seq-first content) raw-link))))
            (push (concat title
                           "\n"
                          (propertize raw-link 'face 'whitespace-space)
                           "\n")
                  links)))
        nil nil 'link)
      (seq-sort 'string-greaterp links))))

The snippet uses org-element to iterate over links to collect/return them in a list. We join both the title and url, so searching can match either of these values. We also add a little formatting (new lines/face) to spiff things up.

(browser-bookmarks  "/private/tmp/bookmarks.org")
(#("Planet Emacslife\nhttps://planet.emacslife.com/\n" 17 46
   (face whitespace-space))
 #("EmacsWiki\nhttps://www.emacswiki.org\n" 10 35
   (face whitespace-space))
 #("Emacs.ch (Mastodon)\nhttps://emacs.ch\n" 20 36
   (face whitespace-space))
 #("Emacs (Stack Exchange)\nhttps://emacs.stackexchange.com\n" 23 54
   (face whitespace-space))
 #("Emacs (Reddit)\nhttps://www.reddit.com/r/emacs\n" 15 45
   (face whitespace-space))
 #("Emacs (Lobsters)\nhttps://lobste.rs/t/emacs\n" 17 42
   (face whitespace-space)))

We can now feed our list to our preferred narrowing framework (ivy, helm, ido, vertico) and use it to quickly select a bookmark. In the past, I've used the likes of ivy-read directly, though have since adopted the humble but mighty completing-read which hooks up to any of the above frameworks.

With that in mind, let's use completing-read to make a selection and split the text to extract the corresponding URL. Feed it to browse-url, and you got your preferred browser opening your bookmark.

(defun  open-bookmark ()
  (interactive)
  (browse-url (seq-elt (split-string (completing-read  "Open: " (browser-bookmarks  "/private/tmp/bookmarks.org"))  "\n") 1)))

I remain a happy ivy user, so we can see its fuzzy searching in action.

emacs-bookmark.gif

At this point, we now have our bookmark-launching Emacs utility. It's only an M-x open-bookmark command away, but we want to make it accessible from anywhere in our operating system, in my case macOS.

Let's enable launching from the command line, though before we do that, let's craft a dedicated frame for this purpose.

(defmacro  present (&rest body)
   "Create a buffer with BUFFER-NAME and eval BODY in a basic frame."
  (declare (indent 1) (debug t))
  `(let* ((buffer (get-buffer-create (generate-new-buffer-name  "*present*")))
          (frame (make-frame '((auto-raise . t)
                               (font .  "Menlo 15")
                               (top . 200)
                               (height . 20)
                               (width . 110)
                               (internal-border-width . 20)
                               (left . 0.33)
                               (left-fringe . 0)
                               (line-spacing . 3)
                               (menu-bar-lines . 0)
                               (minibuffer . only)
                               (right-fringe . 0)
                               (tool-bar-lines . 0)
                               (undecorated . t)
                               (unsplittable . t)
                               (vertical-scroll-bars . nil)))))
     (set-face-attribute 'ivy-current-match frame
                          :background  "#2a2a2a"
                          :foreground 'unspecified)
     (select-frame frame)
     (select-frame-set-input-focus frame)
     (with-current-buffer buffer
       (condition-case nil
           (unwind-protect
               ,@body
             (delete-frame frame)
             (kill-buffer buffer))
         (quit (delete-frame frame)
               (kill-buffer buffer))))))

Most of the snippet styles our new frame and invokes the body parameter. While I don't typically resort to macros, we get a little syntatic sugar here, so we can invoke like so:

(defun  present-open-bookmark-frame ()
  (present (browse-url (seq-elt (split-string (completing-read  "Open: " (browser-bookmarks  "/private/tmp/bookmarks.org"))  "\n") 1))))

Wrapping our one-liner with the present-open-bookmark-frame function enables us to easily invoke from the command line, with something like

emacsclient -ne  "(present-open-bookmark-frame)"

command.gif

Now that we can easily invoke from the command line, we have the flexibility to summon from anywhere. We can even bind to a key shortcut, available anywhere (not just Emacs). I typically do this via Hammerspoon, with some helpers, though there are likely simpler options out there.

 function  emacsExecute(activate,  elisp)
    if activate  then
      activateFirstOf({
            {
               bundleID= "org.gnu.Emacs",
               name= "Emacs"
            }
      })
    end

    local  socket,  found = emacsSocketPath()
    if  not found  then
      hs.alert.show("Could not get emacs socket path")
       return  "",  false
    end

    local  output, success = hs.execute("/opt/homebrew/bin/emacsclient -ne \""..elisp.. "\" -s "..socket)
    if  not success  then
      hs.alert.show("Emacs did not execute: "..elisp)
       return  "",  false
    end

    return output, success
 end

 function  openBookmark()
   appRequestingEmacs = hs.application.frontmostApplication()
   emacsExecute(false,  "(present-open-bookmark-frame)")
   activateFirstOf({
         {
            bundleID= "org.gnu.Emacs",
            name= "Emacs"
         }
   })
 end

hs.hotkey.bind({ "alt"},  "W", openBookmark)

With that, we have our Emacs-powered bookmark launcher, available from anywhere.

launcher.gif

While we used our Emacs frame presenter to summon our universal bookmark launcher, we can likely the same mechanism for other purposes. Maybe a clipboard (kill ring) manager?

kill-ring.png

What would you use it for? Get in touch ( Mastodon / Twitter / Reddit / Email).

Enjoying this content? Find it useful? Consider ✨ sponsoring✨.

-1:-- Building your own bookmark launcher (Post)--L0--C0--November 29, 2023 10:37 PM

Irreal: Making Ad Hoc SQL Tables From Org Tables

This is the coolest thing. Charles Choi—who contributions I’ve written about several times—has a really surprising post on turning Org tables into ad hoc SQL tables. There are a couple of things that make this a worthwhile endeavor:

  1. It’s easy to do
  2. SQL queries that you make on the SQL table are output as a RESULTS block just like any other Org Babel invocation.

If you’re used to using SQL to query a database table and generate new tables or other results, this a a really handy thing. Choi has an example of a query on a simple table that would hard to do otherwise. The SQL table is held in memory and no actual database is generated, just a table corresponding to the Org table but you can make normal SQL queries on that table and export the results to your Org file.

For those who are familiar with SQL spells this is a tremendous capability. You can operate on “normal” Org tables in the same way you do on SQL database tables. Take a look at Choi’s post and his example to see how handy this can be.

-1:-- Making Ad Hoc SQL Tables From Org Tables (Post jcs)--L0--C0--November 29, 2023 05:38 PM

Mike Zamansky: Learning Elisp 15 - cleaning up our minor mode

Today we're finishing off our emoji project. This video covers two quick things.

The first is how we can make the mode use either of our replacement methods - one that actually replaces the text with the emoji and the other that uses text properties to overlay the emoji without changing the text.

This is done with a variable that we can set telling us which function to call. We used one named emoji-replace-by-insert. If it's t (true) we use the replace method, if it's nil we use the overlay one.

We could just use an if statement in our define minor mode but I decided to use this as an opportunity to show how we can assign a function to a variable which might be new to some readers/viewers.

Let's say we want to create a variable named my_function_variable and have it stand in for, let's say the built in 1+ function that increments a value. We could do a simple assignment:

 (setq my_function_variable #'1+)

Unfortunately, in Elisp we can't just call our new variable as a function straight out but rather must call it using funcall, like this:

 (funcall my_variable_function 5) ;; this returns 6, just like (1+ 5) would

In other languages we could just call the function directly. In the case of defining our mode, we can just throw in the variable once we assign it. Here's the code:

(define-minor-mode emoji-replace-mode
"fill in the docstring later"
:lighter " ER"
(let ((func (if emoji-replace-by-insert
#'emoji-replace-insert
#'emoji-replace-overlay)))
(if emoji-replace-mode
(add-hook 'after-change-functions func nil t)
(remove-hook 'after-change-functions func))))

We use the let form to assign our variable func to the appropriate function and then just pass along func when we use add-hook and remove-hook.

That's it.

The other thing we cover involves cleaning up our variables. In earlier videos we used setq but also showed defvar with the practical difference being that defvar had a docstring.

In this video, we look at defcustom which looks like defvar but also lets you change the variable value using emacs' customize-variable command and interface. Further, if we do change the variable this way and save it through the interface, it will save the change in your init.el file for future use. It's a nice touch when making a complete "package."

That's it for this project. I might do one more on setting things up for installation using straight or something similar. If not, it'll be on to the next project which I think will be a thesaurus moed.

Code:

The code for the series is still up here:

-1:-- Learning Elisp 15 - cleaning up our minor mode (Post)--L0--C0--November 29, 2023 03:44 PM

Tory Anderson: Transient for convenience with emms

A new version of Transient, so here’s my media helper This was posted to Reddit.1 With the recent announcement of a new version of Transient, I thought I would post the transient helper I wrote for the deeply customizable built-in-to-emacs emms music player, which I have been enjoying once I stopped thinking of it as Winamp or Spotify or whatever player I used previously. tsa/transient-emms (transient-define-prefix tsa/transient-emms () "EMMS music" :transient-non-suffix 'transient--do-quit-one ["EMMS" ["Controls" ("p" "⏯ Play/Pause" emms-pause) ("s" "⏹ Stop" emms-stop) ("S" "⏲ Seek to time" emms-seek-to) ("n" "⏭ Next" emms-next) ("B" "⏮ Back (Previous)" emms-previous) ("b" "⏪ Back rewind" emms-seek-backward :transient transient--do-stay) ;; I want the transient to stay open on just these commands, so I can easily repeat them ("f" "⏩ Fast-Forward" emms-seek-forward :transient transient--do-stay)] ["Playlist" ("N" "Cue Next" emms-cue-previous) ("P" "Cue Previous" emms-cue-previous) ("r" "🔀 play Random" emms-random) ("R" "🔀 toggle shuffle" emms-toggle-random-playlist) ] ["Global/External" ("d" "📂 emms Dired" emms-play-dired) ("u" "Music dir" tsa/jump-to-music) ;; invokes a bookmark, which in turn hops to my bookmarked music directory ("m" "Modeline" emms-mode-line-mode) ("M" "current info" emms-show) ("e" "emms" emms)] ]) Just bind this to a global key and I start enjoying music and podcasts.
-1:-- Transient for convenience with emms (Post)--L0--C0--November 29, 2023 12:00 AM

Tory Anderson: How to PGP decrypt Deltachat email with Gnus

Intro This message was originally fielded to Reddit1 I’m encrypting some emails on my gmail, sent by an auto-encrypting app. When I try to view them in Gnus, it asks if I want to decrypt the message and, when I affirm, I just see: Error! Result from decryption: Decryption failed Decryption failed This makes sense because I haven’t given it any keys and have never done this email decryption thing.
-1:-- How to PGP decrypt Deltachat email with Gnus (Post)--L0--C0--November 29, 2023 12:00 AM

Mike Zamansky: Learning Elisp Series

Link to source code configuration: https://gitlab.com/zamansky/learning-elisp-code

-1:-- Learning Elisp Series (Post)--L0--C0--November 28, 2023 11:02 PM

Jonas Bernoulli: Transient 0.5 released

I am excited to announce the release of Transient version 0.5, consisting of 134 commits since the last release six months ago.
-1:-- Transient 0.5 released (Post)--L0--C0--November 28, 2023 03:30 PM

Anything goes: Preventing Emacs Window Resizing on Startup

If you set the geometry of your Emacs window in elisp, you may find that the window redraws itself upon resizing. Note that I try to avoid using Xresources to set the geometry which is another solution to this problem. I'd like to control all of my settings in Emacs elisp.

To do this, we will replace default-frame-alist by setting it in the set-initial-frame function which will be associated with the before-init-hook. This hook is run before the frame is drawn preventing the window to resize.

In this example, I set the font to RobotoMono. The width is 170 characters wide and the height is y resolution of the screen less 200 pixels. I also disable other parts of the window like the menu bar, tool bar, and scroll bars.

It would be great if I can control the default background color before my theme kicks in.

(defun set-initial-frame ()
  "Defines and center the frame window"
  (let* ((width-chars 170)
         (height-buffer 200)
         (setq my-font "RobotoMono Nerd Font")
         (monitor-width (x-display-pixel-width))
         (monitor-height (- (x-display-pixel-height) height-buffer)))
    (setq default-frame-alist
          `((width . ,width-chars)
            (height . (text-pixels . ,monitor-height))
            (font . ,my-font)
            ;; Prevent the glimpse of un-styled Emacs by disabling these UI elements early.
            (menu-bar-lines . 0)
            (tool-bar-lines . 0)
            (horizontal-scroll-bars . nil)
            (vertical-scroll-bars . nil)))))

(add-hook 'before-init-hook #'set-initial-frame)

-1:-- Preventing Emacs Window Resizing on Startup (Post tsengf (noreply@blogger.com))--L0--C0--November 28, 2023 06:29 AM

Protesilaos Stavrou: Emacs: I am co-presenting hyperdrive.el at EmacsConf 2023

I am participating at this year’s EmacsConf. The event takes place this weekend: https://emacsconf.org/2023/talks/.

My talk is about hyperdrive.el, a peer-to-peer filesystem in Emacs. I am co-presenting it with Joseph Turner. More information here: https://emacsconf.org/2023/talks/hyperdrive/.

Make sure to tune in for the conference. All the presentations are interesting and it is nice for us to come together as a community.

The hyperdrive video plays during my evening local time. I am available to join live, though I do not know yet if my electricity setup will have enough power left by then (usually I am without power after ~20:30). It depends on the weather. If all goes well, I will be there.

Good luck to everyone involved!

-1:-- Emacs: I am co-presenting hyperdrive.el at EmacsConf 2023 (Post)--L0--C0--November 28, 2023 12:00 AM

Charles Choi: Running SQL Queries on Org Tables

One of the best things in Org Mode are tables and if you know SQL, you have at your disposal the ability to process your tables like a SQL database. Even better, you can run a SQL query on your table without the overhead of manually creating the database. This post shows you how.

SQL Query on Org Table Workflow

To implement an SQL query on an Org table we do the following:

  1. Convert the Org table to a SQLite table via the Org Babel SQLite integration.
    • Inspect the Org table columns to determine its SQL type.
    • Auto-generate the SQL CREATE TABLE statement using the above column types.
    • Store the table in an in-memory database.
  2. Run a SQL query on the above created SQLite table via Org Babel and render its result as an Org table.

Requirements

All code here has been tested on Emacs 29.1 and Org 9.6.11.

  • Have Org Babel SQLite support installed. Instructions for doing this are provided on the Org website.

Demo

Given the following named table example_table, find the aggregate total units per city.

#+NAME: example_table
| site | city          | units |
|------+---------------+-------|
|    1 | San Francisco |   182 |
|    2 | San Francisco |    82 |
|    3 | San Francisco |   124 |
|    4 | Berlin        |   105 |
|    5 | Berlin        |    92 |
|    6 | Seoul         |   104 |
|    7 | Seoul         |    84 |
|    8 | Seoul         |    97 |
|    9 | New York      |   103 |
|   10 | New York      |   140 |

To convert the above Org table to a SQLite table, we will call the named code block cc/org-table-to-sqlite with two arguments as shown below:

  • table which is a reference to the named table, and
  • table-name which is the string representation of table above.

The table name must be SQL-legal.

#+CALL: cc/org-table-to-sqlite(table=example_table, table-name="example_table")

Invoking C-c C-c (org-ctrl-c-ctrl-c) on the above will output the following generated Org SQLite code block.

#+RESULTS:
#+begin_src sqlite :db ":memory:" :var orgtable=example_table :colnames yes
drop table if exists example_table;
create table example_table(site INT, city TEXT, units INT);
.import $orgtable example_table

-- Edit SQL Query Below
select site, city, units from example_table;
#+end_src

A couple of observations of the above generated code:

  1. The database is in-memory allowing for flexibility in changing the Org table.
  2. Every time the code block is executed, the SQL table is dropped if it already exists.
  3. The SQLite column types are determined by examining each column element. (Note: implementation is O(n))
  4. An example SQL SELECT statement is generated using the Org table header.

As we want to determine the aggregate total units per city, let’s modify the above SELECT statement as follows:

select site, city, sum(units) as totals from example_table group by city order by totals;

Invoking C-c C-c on the generated and edited code block yields the following result:

#+RESULTS:
| site | city          | totals |
|------+---------------+--------|
|    4 | Berlin        |    197 |
|    9 | New York      |    243 |
|    6 | Seoul         |    285 |
|    1 | San Francisco |    388 |

Implementation

The Org Elisp code block cc/org-table-to-sqlite is stored in the file cc-org-table-to-sql.org and is posted as a GitHub gist (note click on “Raw” to see all Org markup).

It can be loaded via the org-babel-lob-ingest command as follows:

(org-babel-lob-ingest "cc-org-table-to-sql.org")

Remembering how to invoke the code block cc/org-table-to-sqlite can be bit much. Thankfully we can use YASnippet to help. Shown below is a snippet for creating a named table and call to the code block cc/org-table-to-sqlite referencing said named table.

# name: org-table-to-sqlite
# key: otsql_
# --
#+NAME: ${1:example_table}
| ${2:a} | ${3:b} |
|---|---|
|  1| 10|
$0
#+CALL: cc/org-table-to-sqlite(table=$1, table-name="$1")

Closing Thoughts

Turning an Org table into an ad-hoc SQL database opens a world of possibilities for data journaling and analysis. This post merely scratches the surface of what can be done.

References

-1:-- Running SQL Queries on Org Tables (Post Charles Choi)--L0--C0--November 27, 2023 11:00 PM

Irreal: Denote Dynamic Blocks

For some time, Protesilaos Stavrou (Prot) has been working on an Emacs note taking application that he calls Denote. The system is vaguely reminiscent of a Zettlekasten and has a bunch of nice features. It doesn’t depend on Org mode but integrates nicely with it. You can even set up a Denote capture buffer in Org mode.

As I say, the project has been on-going for some time so there’s lots of information and videos about it. The basic idea is that each note is given a unique name that includes a fine grained time stamp, a title, some optional tags, and an extension. That uniqueness and predictability make it easier to organize your notes.

The purpose of this post is to describe Prot’s latest video reporting on an extension to Denote’s dynamic blocks. The TL;DR is that Denote has a special type of note—called a Meta note—that is denoted by the meta tag. The idea of a Meta note is that it contains information about a collection of other notes. That may include, for example, a commentary or summary of the affiliated notes but it’s also possible to (automatically) include links to those notes. The latest changes, described in the video, provide a way of directly including all or part of the associated notes in the Meta file.

I haven’t paid too much attention to Denote until I saw this video. I felt that Org met my note taking needs and didn’t see a reason to adopt a separate application just for notes. After watching Prot’s video, I may give it a try. I like what he’s done with dynamic blocks. Take a look at the video for the details. It’s only 11 minutes, 46 seconds long so it should be easy to fit in. It may convince you to try out the Denote note taking system.

-1:-- Denote Dynamic Blocks (Post jcs)--L0--C0--November 27, 2023 05:23 PM

Sacha Chua: 2023-11-27 Emacs news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, lobste.rs, kbin, programming.dev, lemmy, communick.news, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

-1:-- 2023-11-27 Emacs news (Post Sacha Chua)--L0--C0--November 27, 2023 03:03 PM

Marcin Borkowski: Clocking in to parent entries

Like many, many Emacs users these days, I’m a heavy user of Org mode. In fact, both of my blogs are written in Org. And while this very blog usually has fairly short entries, my other blog has much longer posts, divided into subsections. This creates a minor problem for me. I track time I spend on writing, but I don’t want to track time spent on individual sections of a blog post. In other words, even if I am in some lower-level heading, when I clock in, I want Org to clock in in the parent heading. Emacs being Emacs, I figured there must be a way to make that happen automatically.
-1:-- Clocking in to parent entries (Post)--L0--C0--November 27, 2023 08:33 AM

Mario Jason Braganza: Weirdly Placed Emacs Org Branches Are Only Cosmetic

Every evening, after my shutdown ritual, I move my current day’s branch to the bottom of my Org Mode file, so I begin the next day at the same fixed place, at line 36.1


The day is done; moving it to the bottom of the pile


Every time I move though, it goes there and sits, right next to the last branch, instead of under it. So I would grumble a bit, and then go hit the return key as required, to get it all right and proper. And I’m tired, so at least one time out of three, I mess the older day too, and then I grumble even more and fix that too.


Where it sits awkwardly


Until today morning, when I realised I had not done my fix the day dance, yesterday…
And the day was correctly positioned at the bottom!
So, was this was just a purely cosmetic issue?!
I tried it with a couple of test days.
I saved, closed, and opened up my file. Fixed!
Then I tried some more tests days and I expanded all my tasks Shift-Tab and and closed them. Fixed! 🙂


Yay! The Org Mode elves fixed it!


I guess, I have to go find something else to be grumpy about now 😂

Update: 2023-11-27

A friend on the fediverse, encouraged me to try filing a bug report with the Org folk.
To which I retort, this is more a PEBKAC problem, than an Org Mode problem.
Most likely I am doing something dumb or I have something misconfigured, or some of my Org helper packages (Org-contrib, Org-ql, Org-Web-Tools, Org Superstar) are trampling over one another.


Feedback on this post? Mail me at feedback@janusworx.com

P.S. Subscribe to my mailing list!
Forward these posts and letters to your friends and get them to subscribe!
P.P.S. Feed my insatiable reading habit.



  1. As I grow older, habits, routines and static places are growing ever more important, so I can function well. ↩︎

-1:-- Weirdly Placed Emacs Org Branches Are Only Cosmetic (Post)--L0--C0--November 27, 2023 02:56 AM

Tony Zorman: Integrating Zsh's History Into Eshell

Posted on 2023-11-27  ·  2 min read  · 

I use eshell as my main shell. Still, a terminal emulator with zsh is kept around for longer running processes and scratchpads. One thing that’s essential for this setup to make sense is that eshell and zsh share the same history file. Sadly, this doesn’t work out of the box: zsh stores its history in a metafied format—nothing that’s not fixable on the Emacs side, of course!

This email explains the problem quite well. In short:

[…] when 0x80-0x9F characters are used, then always 0x83 Meta character is inserted and following character is bit shifted, […]

This is not a bug, but expected behaviour; zsh’s history is saved in exactly such a metafied format. The upshot is that, when setting eshell-history-file-name to e.g. "~/.config/zsh/zsh_history", Emacs either won’t know how to properly encode the file upon exiting eshell, or one will get suggestions—using a package like esh-autosuggest—containing garbage like \304§ instead of ć.

The linked discussion helpfully contains a small C program to unmetafy the history:

#define Meta ((char) 0x83)

/* from zsh utils.c */
char *unmetafy(char *s, int *len)
{
  char *p, *t;

  for (p = s; *p && *p != Meta; p++);
  for (t = p; (*t = *p++);)
    if (*t++ == Meta)
      t[-1] = *p++ ^ 32;
  if (len)
    *len = t - s;
  return s;
}

This looks pretty terse, at least to my non-C-reading-eyes, but essentially every time 0x83 is encountered, we delete it and XOR the following character with the number 32. An implementation in elisp might look like the following:

(defun slot/unmetafy ()
  (cl-flet ((unmetafy (input)
              (let ((i 0) output)
                (while-let ((char (nth i input))
                            (inc-and-char
                             (if (= char #x83)
                                 ;; Skip meta character and unmetafy.
                                 `(2 . ,(logxor (nth (1+ i) input) 32))
                               ;; Advance as usual.
                               `(1 . ,char))))
                  (cl-incf i (car inc-and-char))
                  (setq output (cons (cdr inc-and-char) output)))
                (decode-coding-string
                 (apply #'unibyte-string (nreverse output))
                 'utf-8-unix
                 t))))
    (let ((hist-file "~/.config/zsh/zsh_history"))
      (with-temp-buffer
        (insert (mapconcat (-compose #'unmetafy #'string-to-list)
                           (s-lines (f-read-bytes hist-file))
                           "\n"))
        (write-file hist-file)))))

This can be conveniently integrated into an eshell/exit-like function, such as

(defun slot/eshell-exit (&optional arg)
  "Exit eshell and kill the current frame."
  (interactive "P")
  (slot/unmetafy)
  (eshell-write-history)
  (save-buffers-kill-terminal))

Finally, one just need to take care to bind that function to a key, and to unmetafy the history when eshell starts.1

(use-package eshell
  :hook (eshell-hist-load . slot/unmetafy)
  :bind (:map eshell-mode-map
              ("C-x C-c" . slot/eshell-exit)))

  1. Unmetafying when quitting resolves the “Emacs can’t decide on an encoding” issue, and doing so at the start solves esh-autosuggest et al producing garbage suggestions.↩︎

-1:-- Integrating Zsh's History Into Eshell (Post)--L0--C0--November 27, 2023 12:00 AM

Protesilaos Stavrou: Emacs: ‘standard-themes’ version 2.0.0

The standard-themes are a pair of light and dark themes for GNU Emacs. They emulate the out-of-the-box looks of Emacs (which technically do NOT constitute a theme) while bringing to them thematic consistency, customizability, and extensibility. In practice, the Standard themes take the default style of the font-lock and Org faces, complement it with a wider and harmonious colour palette, address many inconsistencies, and apply established semantic patterns across all interfaces by supporting a large number of packages.

Below are the release notes.


Deprecated several user options that changed colours

The following user options are deprecated in favour of palette overrides (more in the following section):

  • standard-themes-mode-line-accented
  • standard-themes-links
  • standard-themes-region
  • standard-themes-fringes

In the same spirit, the user option standard-themes-prompts no longer affects colours.

All colour-related tweaks are done via palette overrides

In previous versions of the themes, we provided certain hardcoded colour variations, such as for an “accented” mode line and more “intense” fringes. We no longer do so, in favour of a more flexible approach that empowers the user to pick the exact colour they like.

The Standard themes provide the means to override every entry in their palette. Each palette defines named faces (such as what is the exact hexademical Red-Green-Blue value of blue-warmer) as well as semantic colour mappings (like bg-mode-line-active). Users can configure either the standard-themes-common-palette-overrides or the theme-specific ones, standard-dark-palette-overrides, standard-light-palette-overrides.

Refer to the manual for how this can be done: https://protesilaos.com/emacs/standard-themes#h:34fe0582-960b-45dc-af5d-23c8f3e9d724. And/or use the commands to preview the palette: standard-themes-preview-colors, standard-themes-preview-colors-current. Below is a sample:

(setq standard-themes-common-palette-overrides
      '((cursor red-warmer)
        (bg-mode-line-active bg-blue-subtle)))

[ This is the same functionality found in my modus-themes and ef-themes. Modus has the most palette entries and widest package support due to its maximalist scope. ]

The standard-themes-prompts accept any typographic weight

This user option applies to prompt texts of all sorts, such as the minibuffer and command-line shells. It now accepts any supported typographic weight as part of its value. The list of weights are recorded in the documentation of the variable standard-themes-weights as well as the manual.

Headings have more semantic colour mappings associated with them

Apart from the foreground, each heading level from 0 to 8 now has a background and an overline. These new palette entries are set to the unspecified value, meaning that they do not have any visual effect. Users can set them to a colour via palette overrides to have headings with a background and/or an overline (per heading level).

Building on the previous sample code with the overrides:

(setq standard-themes-common-palette-overrides
      '((cursor red-warmer)
        (bg-mode-line-active bg-blue-subtle)

        ;; Extra space for didactic purposes

        (fg-heading-1 rainbow-1)
        (fg-heading-2 rainbow-2)

        (bg-heading-1 bg-blue-nuanced)
        (bg-heading-2 bg-yellow-nuanced)

        (overline-heading-1 blue-faint)
        (overline-heading-2 yellow-faint)

        ))

Always remember to reload the theme for changes to take effect.

Contact me if you need any help.

Space-related semantic colour mappings are available

The whitespace-mode and related faces now use new palette entries that are specific to them. This means that users can easily make space characters more intense/subtle. As part of this redesign, the background that was enabled by default is now removed to accommodate uses of whitespace-mode in spacing-sensitive programming modes: an intensely coloured background on every space makes it hard to edit the text.

The display-line-numbers-mode benefits from semantic colour mappings

A new subset of palette entries applies to line numbers. It covers foreground and background values for the current/other line numbers. Users can style them as they see fit by using palette overrides. For example, this makes line numbers have a subtle grey backgrounds to not be mistaken for the contents of the buffer:

(setq standard-themes-common-palette-overrides
      '((cursor red-warmer)
        (bg-mode-line-active bg-blue-subtle)

        ;; Extra space for didactic purposes

        (fg-heading-1 rainbow-1)
        (fg-heading-2 rainbow-2)

        (bg-heading-1 bg-blue-nuanced)
        (bg-heading-2 bg-yellow-nuanced)

        (overline-heading-1 blue-faint)
        (overline-heading-2 yellow-faint)

        (bg-line-number-active bg-active)
        (bg-line-number-inactive bg-dim)

        ))

More semantic colour mappings for dates

The palette of each theme now defines an expanded subset of entries for dates. These include, among others, what we find in the Org agenda and the M-x calendar, such as date-weekday, date-scheduled, and more. Use palette overrides to tweak them accordingly.

More packages are supported

Support for more packages means that the theme looks consistent across a variety of interfaces (this is, after all, the original idea behind the standard-themes otherwise an unthemed Emacs looks too inconsistent—sorry!). For this version, we include the following in an already long list:

  • breadcrumb
  • centaur-tabs
  • corfu-candidate-overlay
  • jit-spell
  • nerd-icons
  • nerd-icons-dired
  • nerd-icons-ibuffer
  • vundo
  • which-key

Ediff faces do not implicitly depend on diff-mode

The Ediff faces used to inherit from the built-in diff-mode. This introduced a dependency and so using something like M-x ediff-files before loading diff-mode would result in an error. Ediff faces are thus designed to stand on their own.

“Flagged” and “trashed” emails are now distinct

They used to have the same colour, but this is no more. The change covers the mu4e and notmuch packages.

Miscellaneous

  • Revised the colour value of the standard-dark bg-region palette entry. The previous one was the same as the original colour used by the region face against a dark background: an intense blue. The new value is still blue, though it is toned down to do what it needs to do without exaggerations. (Remember that the point of the standard-themes is to be faithful to the defaults, but I still apply judgement where I think improvements can be made without changing the character of the themes).

  • Added support for the appt-notification face (which I introduced in Emacs 30).

  • Extended support for the various flymake “echo” and “end of line” faces (e.g. flymake-error-echo, flymake-end-of-line-diagnostics-face).

  • Removed the deprecated consult-preview-cursor face. This was done in commit 267b0c9 on the Consult Git repository. Discussed here: https://github.com/minad/consult/issues/764#issuecomment-1537491625.

  • Revised colours used in the all-the-icons faces. They now look more consistent.

  • Deleted the underline from the org-ellipsis face. Org files are already too busy and we do not need more of that.

  • Made the eglot-diagnostic-tag-unnecessary-face look like a warning. By default it inherits the ‘shadow’ face, which makes it counter-intuitive as it dims the text instead of bringing it to our attention. The intent of eglot-diagnostic-tag-unnecessary-face is to highlight unused symbols, so this is better presented as a warning.

    Thanks to Augusto Stoffel for bringing this matter to my attention. This was done via a private channel and the information is shared with permission.

  • Rewrote most of the manual to remove the deprecated user options, expand the documentation where necessary, and tweak the sample configuration.

  • Expanded the deftheme definition of each theme’s metadata. This is to support new features in Emacs where themes can specify the set they belong to, as well as whether they are light or dark. The built-in command is theme-choose-variant. This is in response to Emacs bug#65468: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=65468. Thanks to Mauro Aranda for bringing this matter to my attention.

  • Replaced function calls that depended on cl-lib.el with equivalent ones from seq.el. The latter is loaded by default and we did not need the CL features, anyway.

-1:-- Emacs: ‘standard-themes’ version 2.0.0 (Post)--L0--C0--November 27, 2023 12:00 AM

Irreal: Winner Mode

Ken Huang over at whatacold’s space has a very useful post on Emacs’ winner mode. I was familiar with the name “winner mode” long before I started using it but the name seemed slightly off-putting and offered no clue as to what it did so I ignored it. Later, I somehow discovered1 what it actually did and I’ve been a dedicated user ever since.

The TL;DR is that it will restore your previous window configuration(s). The typical use case is that you perform some temporary action, such as invoking HELP, and afterwards want to return your window configuration to what it was. Winner mode maintains a stack of window configurations so you can restore configurations older than the previous one.

You can also move forward to reestablish the last replaced configuration. The problem with that is that you can move forward only one configuration but I’ve never found that a problem because I almost never want to do that.

One potential problem that Huang points out is that moving back several configurations can be awkward because the default binding is Ctrl+c
, which is slightly hard to type. Huang offers a nice solution for this: a hydra that you invoke with Ctrl+c w and then simply type p to move backward for each configuration.

If you’re a winner-mode user, you may be interested in his hydra. If you want to see it in action, Huang has an embedded video demonstrating winner mode and the hydra. The video is just over 12 minutes so plan accordingly.

Footnotes:

1

Oh. It turns out it was yet more good advice from Phil.

-1:-- Winner Mode (Post jcs)--L0--C0--November 26, 2023 04:56 PM

Alvaro Ramirez: Native Emacs/macOS UX integrations via Swift modules

25 November 2023 Native Emacs/macOS UX integrations via Swift modules

Once you learn a little elisp, Emacs becomes this hyper malleable editor/platform. A live playground of sorts, where almost everything is up for grabs at runtime. Throw some elisp at it, and you can customize or extend almost anything to your heart's content. I say almost, as there's a comparatively small native core, that would typically require recompiling if you wanted to make further (native) mods. But that isn't entirely true. Emacs 25 enabled us to further extend things by loading native dynamic modules, back in 2016.

Most of my Emacs-bending adventures have been powered by elisp, primarily on macOS. I also happen to have an iOS dev background, so when Valeriy Savchenko announced his project bringing Emacs dynamic modules powered by Swift, I added it to my never-ending list of things to try out.

Fast-forward to a year later, and Roife's introduction to emt finally gave me that much-needed nudge to give emacs-swift-module a try. While I wish I had done it earlier, I also wish emacs-swift-module had gotten more visibility. Native extensions written in Swift can open up some some neat integrations using native macOS UX/APIs.

While I'm new to Savchenko's emacs-swift-module, the project has wonderful documentation. It quickly got me on my way to build an experimental dynamic module introducing a native context menu for sharing files from my beloved editor.

emacs-share.webp

Most of the elisp/native bridging magic happens with fairly little Swift code:

 try env. defun(
   "macos-module--share",
  with:  """
     Share files in ARG1.

     ARG1 must be a vector (not a list) of file paths.
     """
) { (env: Environment, files: [ String])  in
   let urls = files. map {  URL(fileURLWithPath: $0) }

   let picker =  NSSharingServicePicker(items: urls)
   guard  let view = NSApp. mainWindow?. contentView  else {
     return
  }

   let x =  try env. funcall("macos--emacs-point-x")  as  Int
   let y =  try env. funcall("macos--emacs-point-y")  as  Int

   let rect =  NSRect(
    x: x + 15, y:  Int(view. bounds. height) - y + 15, width: 1, height: 1
  )
  picker. show(relativeTo: rect, of: view, preferredEdge: . maxY)
}

This produced an elisp macos-module--share function I could easily access from elisp like so:

(defun  macos-share ()
   "Share file(s) with other macOS apps.

 If visiting a buffer with associated file, share it.

 While in ` dired ', any selected files, share those.  If region is
 active, share files in region.  Otherwise share file at point."
  (interactive)
  (macos-module--share (vconcat (macos--files-dwim))))

On a side note, (macos--files-dwim) chooses files depending on context. That is, do what I mean (DWIM) style. If there's a file associated with current buffer, share it. When in dired (the directory editor, aka file manager), look at region, selected files, or default to file at point.

(defun  macos--files-dwim ()
   "Return buffer file (if available) or marked/region files for a ` dired ' buffer."
  (if (buffer-file-name)
      (list (buffer-file-name))
    (or
     (macos--dired-paths-in-region)
     (dired-get-marked-files))))

(defun  macos--dired-paths-in-region ()
   "If ` dired ' buffer, return region files.  nil otherwise."
  (when (and (equal major-mode 'dired-mode)
             (use-region-p))
    (let ((start (region-beginning))
          (end (region-end))
          (paths))
      (save-excursion
        (save-restriction
          (goto-char start)
          (while (< (point) end)
             ;;  Skip non-file lines.
            (while (and (< (point) end) (dired-between-files))
              (forward-line 1))
            (when (dired-get-filename nil t)
              (setq paths (append paths (list (dired-get-filename nil t)))))
            (forward-line 1))))
      paths)))

I got one more example of a native macOS integration I added. Being an even simpler one, and in hindsight, I prolly should have introduced it first. In any case, this one reveals dired files in macOS's Finder app (including the selection itself).

reveal.webp

 try env. defun(
   "macos-module--reveal-in-finder",
  with:  """
     Reveal (and select) files in ARG1 in macOS Finder.

     ARG1 mus be a vector (not a list) of file paths.
     """
) { (env: Environment, files: [ String])  in
  NSWorkspace. shared. activateFileViewerSelecting(files. map {  URL(fileURLWithPath: $0) })
}

The corresponding elisp is nearly identical to its macos-share sibling:

(defun  macos-reveal-in-finder ()
   "Reveal file(s) in macOS Finder.

 If visiting a buffer with associated file, reveal it.

 While in ` dired ', any selected files, reveal those.  If region is
 active, reveal files in region.  Otherwise reveal file at point."
  (interactive)
  (macos-module--reveal-in-finder (vconcat (macos--files-dwim))))

My Swift module experiment introduces two native macOS UX integrations, now available via M-x macos-share and M-x macos-reveal-in-finder. I've pushed all code to it's own repo.

I hope this post brings visibility to the wonderful emacs-swift-module project and sparks new, native, and innovative integrations for those on macOS. Can't wait to see what others can do with it.

Enjoying this content? Find it useful? Consider ✨ sponsoring✨.

-1:-- Native Emacs/macOS UX integrations via Swift modules (Post)--L0--C0--November 25, 2023 07:30 PM

whatacold: Join Every N Lines By A Separator in Emacs

It has been some time since I came along the idea of the w/join-lines command to join lines. After that, sometimes I found that it would be even better to join every a few lines. Let's see the example below, suppose we've copies some data from somewhere, and now we want to yank it into an Emacs buffer and slightly modify it to be like an matrix. That is, make it from:
-1:-- Join Every N Lines By A Separator in Emacs (Post whatacold (whatacold@gmail.com))--L0--C0--November 25, 2023 04:24 AM

Protesilaos Stavrou: Emacs: Denote Org dynamic blocks

Raw link: https://www.youtube.com/watch?v=zzXcav0yb50

In this video I demonstrate Denote’s Org dynamic blocks facility. I focus on the new ‘denote-files’ Org dynamic block that I am developing. In short, this new block lets you include the contents of files with the option to also add links to them as well as to omit their front matter from the block. It is a neat way to quickly consolidate your writings on a given topic.

-1:-- Emacs: Denote Org dynamic blocks (Post)--L0--C0--November 25, 2023 12:00 AM

Karthik Chikmagalur: Different Strokes For Different Folks

A modest defense of the rodent

So, Emacs and the mouse. This is an unexpectedly contentious topic, with discussions that end, at best, with careless dismissal. More often they turn into arguments with folks talking past one another.

The advantages of using the mouse for common actions in Emacs are immediate and obvious. Window selection is a natural extension of basic mouse usage. Resizing windows is a snap. Context (right-click) menus See context-menu-mode. and drag and drop support, which improve with each new Emacs release, are very intuitive. The mouse provides access to basic editor functions with no learning curve, and no exhortations to work through the Emacs tutorial are necessary. Also, feature discoverability via Emacs’ menu-bar is surprisingly good.

Unfortunately, I have to address the rodent in the room carefully before we can talk about mitigating the many disadvantages of mouse-first interaction, since Emacs users tend to be very opinionated about this topic. Ergonomics, speed, and efficiency are three common reasons people advocate for the keyboard against the mouse for non-graphical work. I’m not convinced any of these arguments hold water. The first two are research-worthy topics on their own, with many quotable precedents, and beyond my ability to argue for or against convincingly just from personal experience Besides, anyone who’s had bouts of RSI has made up their mind already on this topic. . On the matter of speed, for instance, I am obliged to include this quote because y’all are going to send me emails linking to it otherwise:

We’ve done a cool $50 million of R & D on the Apple Human Interface. We discovered, among other things, two pertinent facts:

Test subjects consistently report that keyboarding is faster than mousing.

The stopwatch consistently proves mousing is faster than keyboarding.

Bruce Tognazzini

So let’s pretend for the purpose of today’s discussion that we’re not concerned about the difference in editing speed one way or another.

In the context of Emacs specifically, there are further disadvantages. For example, mouse actions compose in limited ways (such as when dragging to form selections) and cannot build on each other like key sequences can with prefix keys and transient maps. You can’t automate mouse usage with keyboard macros easily.

But today we’re primarily going to address the third reason: efficiency.

I find the arguments about efficiency, in the sense of poor expressivity or economy of motion, shortsighted at best. Here are two facets of this argument, where “mouse” includes any kind of pointing device.

Economy:

Frequent context switching between the keyboard, mouse and keyboard+mouse is wasteful and causes low amounts of constant friction.

Expressivity:

Mouse usage has a low ceiling: it makes easy tasks trivial but involved actions impossible. Adding buttons or widgets to the screen doesn’t scale.

Economy and interprogram contexts

Economy first. I actually agree with the context switching argument, to the extent that the friction of repeated switching feels progressively more annoying. But the conclusion – it’s best to avoid the mouse to avoid context switching – is shortsighted because it only applies if you’re only ever in Emacs and never have to use the mouse, or conversely if you’re never in a text editor and always in a mouse-driven (or keyboard+mouse driven) application like a 3D modeling tool or a big commercial IDE. Most of us are somewhere in the middle.

I’m as keyboard-centric as you can reasonably get: besides Emacs, I use a tiling window manager, a keyboard-driven web browser and mostly TUI applications. Keybindings are the topic I’ve written the most about on this website – an embarrassing amount of yakshaving devoted to an inane subject. Even so, I use the mouse frequently because it’s often the best way to select text, images and links, do graphical work, and to interact with (both simple and complex) GUI software.

When working on something that involves Emacs and one of these mouse driven applications, having to move over to the keyboard for the Emacs bit is exactly the friction we’d like to avoid. The other app may not be flexible, but Emacs is! So we don’t need to switch to the Emacs-typical both-hands-at-keyboard context. Here are a few examples of quick interprogram interaction involving Emacs that you can easily do without moving your hand off the mouse.

Pasting text from other applications into a new buffer

Switch to a scratch buffer+window in Emacs to paste some text:

I use a mouse gesture in Emacs to create a scratch buffer in Org mode – courtesy of the scratch package – then drag some text into it Incidentally, the text is a LaTeX environment that is rendered automatically via Org’s new LaTeX preview system. . I then switch back to the previous buffer using another mouse gesture.

git-clone from a repository URL

Middle click to paste a link from the clipboard. (This is only for clarity, it’s unrelated to the actual action.) Then use a mouse gesture to git-clone from that link to a prespecified directory.

open a project directory in dired so we can drag and drop a file

Use a mouse gesture to bring up a list of directories in the active project. Pick one – also using the mouse – then drag an image file into dired before switching back.

mpv + live video transcript in Emacs

Control mpv (a video player) by clicking around in a live transcript file in Emacs:

No mouse gestures here – the clickable transcripts and mpv connection are provided by elfeed-tube, which was designed to be usable with the mouse since it involves interacting with a video player.

My counter-argument can be summarized: Use the lowest effort means of interaction in each context you work in. Often this means driving Emacs with the mouse.

Expressivity

The expressivity counterargument: Buttons and widgets indeed don’t scale, but they bear the additional burdern of discoverability. Mouse interactions in Emacs don’t have to be prescribed or discoverable – when they are actions we set up, typically after repeatedly observing a cumbersome task that could be mouse-driven. Point-and-click in an editor is not as expressive as full-on keyboard usage, but that’s only true in the generic sense. The relevant question is if we can express the specific verbs that we care about, and from the above demos it’s clear we can.

An example: considering that using the mouse to select and resize windows is already a more natural experience than spamming C-x o and friends (or your evil-mode equivalents), it is possible to extend it to be a more comprehensive approach to window and buffer management:

This demo showcases the use of mouse gestures to do the following:

  • Split the frame vertically and horizontally
  • Delete windows
  • Cycle through buffers in windows by left and right clicking the buffer name in the mode line.
  • Delete other windows
  • Swap windows to the right and left
  • Toggle between the last two buffers shown in a window
  • Go back to a previous window configuration (via tab-bar-history-back or winner-undo)

How to mouse around

This is not, strictly speaking, an article on how to use the mouse in Emacs – it’s more about why and when. For the how I suggest reading Philip Kaludercic’s write-up. You could also try just clicking around, especially in the mode line! However the use of gestures in Emacs rarely gets much attention, so here we go.

For once, this is going to be a short description, since this is a batteries included situation. Emacs ships with everything you need.

Adding mouse gesture support to Emacs is easy with the included Strokes library Many thanks to David Bakhash and the Emacs maintainers for strokes.el. . For each action you want to map to a gesture,

  1. Find or (optional) write a command that does the thing.
  2. Set it to a mouse stroke (gesture) with strokes-global-set-stroke.

That’s it M-x strokes-help has more information. .

Optionally, you could change the mouse button you hold down to perform a gesture. The default is S-mouse-2, which is rather awkward. I use a side button on my mouse (typically the “forward” button):

(keymap-global-set "<down-mouse-9>" 'strokes-do-stroke)

Also optionally, you can hide the live-display of the stroke as you draw (strokes-use-strokes-buffer) – I left it in for clarity in the demos.

I’ve not had to customize anything else about the strokes library, but feel free to explore – it has support for multi-glyph (complex) strokes, for instance.

There are a few general mouse settings you might be interested in:

  • mouse-autoselect-window: Set to t for focus-follows-mouse behavior inside Emacs. Typically what you’d want if you use mouse gestures.
  • mouse-drag-and-drop-region: To enable text drag-and-drop within Emacs,
  • mouse-drag-and-drop-region-cross-program: (Emacs 29+) and across programs from Emacs.
  • dired-mouse-drag-files: To drag files from dired to other programs.

Improving Strokes

Mouse gestures are a decades-old concept, as many features included with Emacs are. And the Strokes library has a list of notes and todos, as many features included with Emacs do.

  1. No contextual actions: The use of strokes is limited, as of Emacs 29, by the lack of support for mode-specific or buffer-local strokes. This means the same gesture cannot do different things in different contexts without writing cumbersome, bespoke dispatch commands to handle this.
  2. Somewhat unreliable gesture matching: Drawing with the mouse or trackpad is fuzzy and imprecise. The matching algorithm is quite rudimentary and there are mismatches when you have many strokes defined (> 25, let’s say), even with an increased “grid” resolution when drawing. Fixing 1 can take the pressure off the matching algorithm, but we could also use a more sophisticated approach to matching.
  3. No multi-touch gestures: This can increases the dimensionality of the gesture space, allowing for a greater number of “basic strokes” – although the OS usually captures and maps most of these for its window management.

Despite these limitations, this is a very handy tool. I’m not sure why gestures aren’t more common – we only see them on touch interfaces these days. You can draw them anywhere on the screen, and they tolerate a fair bit of fuzz. They avoid the problem of having to move the mouse over to a small target on screen. Not having to fill the screen up with buttons is a win by itself. The only significant problem appears to be that they’re not (re)discoverable, but this isn’t a problem inside Emacs: we have strokes-describe-stroke (like describe-key) and strokes-list-strokes.

It’s not all or nothing. It’s not even something.

Some of the “talking past each other” I mentioned in the beginning is because of assumptions we make about using the mouse in text editors. We gravitate to one of two specious requirements:

  • The mouse should substitute for the keyboard, such as when using menu or toolbar buttons instead of keybindings.
  • The mouse should complement the keyboard, so we work best with a hand each on the keyboard and mouse. (This is the Acme editor approach.)

Actual usage patterns are messier than either of these. Sometimes we’re working in a mouse-heavy context, sometimes it’s two handed keyboarding, sometimes its a mix. Often the editor is at the periphery of the task at hand, sometimes it’s dead center This is true despite Emacs swallowing up my desktop applications. Calendar, email, reading, some web browsing… the list keeps growing. . Any degree of flexibility on the part of the editor is welcome. Instead of dismissing the mouse on the basis of the available design affordances, it can help to think about what we actually care to avoid – frequent context switching for me, your answer will be different – and how driving Emacs with the mouse helps us do that.

-1:-- Different Strokes For Different Folks (Post)--L0--C0--November 24, 2023 11:15 PM

Irreal: Interactive Java

Those of you who have been around Irreal for awhile have heard me preach the gospel of interactive (or exploratory) programming before. I consider it the absolute best and most pleasing way to program. The problem is that it requires a REPL, which not every language offers.

Java is one of those languages that does have a REPL although you almost never hear about it. As far as I can tell, the REPL is merely a way of letting you type in a line input and get the corresponding output: not too useful.

Not too useful unless you’re using Musa Al-hassy’s REPL driven development package. It enables you to use interactive programming techniques with Java as well as several other languages.

Here he is putting together a Java-based photo display application using the interactive programming method. Notice how it’s easy to experiment by making a small change to see how things work before writing the more complex code that does what you want for the final application.

I don’t know Java at all so I can’t comment on whether or not is code is optimal or even good but I do know about interactive programming and can report that he’s captured the method very well. If you’re a Java programmer—or, really, a user of any other REPL enabled language—you should definitely take a look at this video. The video is only 10 minutes, 18 seconds so it should be easy to find some time for it.

-1:-- Interactive Java (Post jcs)--L0--C0--November 24, 2023 04:42 PM

Discovering Emacs podcast: Making Incremental Search Work for You in Emacs - EP3

-1:-- Making Incremental Search Work for You in Emacs - EP3 (Post Discovering Emacs)--L0--C0--November 24, 2023 01:08 AM

Protesilaos Stavrou: Emacs: spacious-padding version 0.2.0

This package provides a global minor mode to increase the spacing/padding of Emacs windows and frames. The idea is to make editing and reading feel more comfortable. Enable the mode with M-x spacious-padding-mode. Adjust the exact spacing values by modifying the user option spacious-padding-widths.

Release notes below.


[ I provide screenshots in a recent publication: https://protesilaos.com/codelog/2023-11-15-spacious-padding-extra-ui-dev/ ]

The package is stable and works well. This set of changes expands the concept of “spacious padding” to more user interface elements, namely:

  • active and inactive mode lines;
  • header line;
  • the tab-bar-mode.

The user option which sets all the width values is spacious-padding-widths. It now reads keywords that correspond to the aforementioned elements. Concretely, here are the defaults:

(setq spacious-padding-widths
      '( :internal-border-width 15
         :header-line-width 4
         :mode-line-width 6
         :tab-width 4
         :right-divider-width 30
         :scroll-bar-width 8))

After changing the widths, reload the spacious-padding-mode for changes to take effect.

I have taken care to make ‘spacious-padding-mode’ work even when the spacious-padding-widths does not include all keywords. This means that the previously supported value will continue to work (the previous value did not have the keywords header-line-width, mode-line-width, and tab-width).

-1:-- Emacs: spacious-padding version 0.2.0 (Post)--L0--C0--November 24, 2023 12:00 AM

Discovering Emacs podcast: Using Whitespace Mode in Emacs - EP4

-1:-- Using Whitespace Mode in Emacs - EP4 (Post Discovering Emacs)--L0--C0--November 23, 2023 09:45 PM

Irreal: Should I Learn Elisp?

Fate_sc over at the Emacs subreddit asks if he should bother to learn Elisp. He’s fairly new to Emacs and is willing to learn Elisp but wonders if it would be worth his while. You see this type of question a lot.

One of Fate_sc’s concerns is that Elisp is “not like” other programming languages and is therefore hard to learn. It’s true that Lisps are different from most other languages but that’s actually a good thing. It’s good because the language has virtually no syntax and is easy to learn. What does make it difficult is the huge run time library. There are hundreds of functions performing all sorts of tasks and in Lisp virtually all actions are realized through functions.

The thing is, though, you don’t have to learn the entire library to be productive. As I’ve said previously, even after more than 15 years I still don’t know all—or even a majority—of the available functions. But as with learning Org, there’s no need to master the whole library to be productive. You can, as Mike Zamansky is currently demonstrating over at C’est La Z, program significant functionality with just a little Emacs. In short, it’s a long journey but one in which you can be highly productive along the way.

The commenters to Fate_sc’s post all agree that it is worthwhile but that each user has to decide for themselves what level of mastery is appropriate for their needs. And it is, as I say, a lot like learning Org: you first learn just enough to make some simple configurations, then a simple editing function, and, then before you know it, you’ll be able to add significant functionality to your Emacs.

Update [2023-11-27 Mon 10:28]: Added link to the reddit post.

-1:-- Should I Learn Elisp? (Post jcs)--L0--C0--November 23, 2023 04:28 PM

William Denton: Exporting Org source code blocks to LaTeX with minted

Recently I spent much longer than expected generating data about library holdings for an insurance spreadsheet needed by CURIE. We don’t have to do it often, and this was the first time I’d had to figure out the numbers they want about total books on the shelf (by LCC class letter) and years of print journal holdings (by subject groupings based on LCC). Cleaning the messy bibliographic metadata—all bibliographic metadata is messy—took a number of steps, and naturally I did it with R in Org, documenting everything in a reproducible way so that next time it will just take me an afternoon, not days and days.

Interesting fact: the Scott Library has about 250,000 years of print journals on the shelves.

So that others can see what data cleaning and munging was done, I exported the Org file to LaTeX and then turned it into a PDF. I included the R source code and wanted to make that look nice, not just plain verbatim text. This got me looking at the LaTeX package minted for the first time. Here I document how I now have things set up.

In my Emacs config I set up a function to turn minted on or off. Originally I added minted to the default list of packages in every LaTeX export and defined that every source code listing should be formatted with minted, like so:

(add-to-list 'org-latex-packages-alist '("" "minted" nil))
(setq org-latex-src-block-backend 'minted)

About the first line, a lot of documentation says the variable to set is org-latex-listings but as of Org 9.6 that is obsolete. As to the second, with that back end variable set, every block will be inside \begin{minted} and \end{minted} instead of \begin{verbatim} and \end{verbatim}.

But when minted is one of the included packages it’s always necessary to run pdflatex -shell-escape to compile the PDF, even if there are no source blocks. I can’t be having that.

Instead, I use this function (based on a tip from Xah Lee) to toggle those settings on or off. When I’m working on a file that I want to export using minted, I run M-x wtd/org-toggle-minted to turn things on. When I’m done, I run it again to turn things off.

(defun wtd/org-toggle-minted ()
  "Toggle whether or not Org should use minted for LaTeX."
  (interactive)
  (if (get 'wtd-org-minted-on-or-off 'state)
      (progn
	(setq org-latex-packages-alist (delete '("" "minted" nil) org-latex-packages-alist))
	(setq org-latex-src-block-backend 'verbatim)
	(put 'wtd-org-minted-on-or-off 'state nil)
	(message "Minted is off")
	)
    (progn
      (add-to-list 'org-latex-packages-alist '("" "minted" nil))
      (setq org-latex-src-block-backend 'minted)
      (put 'wtd-org-minted-on-or-off 'state t)
      (message "Minted is on; use pdflatex -shell-escape -interaction=nonstopmode")
      )
    )
  )

(My arrangement of parentheses probably offends many people, but I don’t do much Lisp and I find it helpful here.)

Now, minted has all sorts of options. They can be set in an association list that will be passed to every source block, like so.

(setq org-latex-minted-options
      '(("frame" "leftline")
))

However, this seems inelegant to me. It puts the same text on every code block, over and over, and I would rather specify the options once in LaTeX. Also, I don’t think I’ll want the same look on everything I do; I want to be able to control document-specific options right in the Org file. Therefore I prefer to define options with \setminted{} in a latex_header at the top of the Org file.

Here’s an example. The file starts with minted settings (I don’t need usepackage because it’s already done, thanks to the above). This says that I want to use one of the Solarized colour schemes (see the listing of Pygments styles) and put a line on the left of every block. For R code, I want line numbers.

#+latex_header: \setminted{style=solarized-light,frame=leftline}
#+latex_header: \setminted[r]{linenos=true}

Here’s an R block. I throw in an option for this block specifically, to change the frame setting so there’s a line around the whole block.

#+attr_latex: :options frame=single
#+begin_src R
library(purrr)
fruits <- c("apple", "pear", "grape", "blueberry")
map(fruits, \(f) nchar(f))
#+end_src

(I know that nchar(fruits) is the proper way, but I was using purrr seriously for the first time in the CURIE work and thought what the hell.)

In my Emacs (where I use the dark Solarized theme), this looks like so:

Formatted R code in Org Formatted R code in Org

When turned into a PDF, I get:

Nicely formatted code from the PDF Nicely formatted code from the PDF

That looks good!

It’s in a box because I overrode the frame setting, it has line numbers because I set that for R, and it uses the Solarized light theme because that is the document setting.

Next, here’s a Ruby block.

#+attr_latex: :options style=default,fontsize=\footnotesize
#+begin_src ruby
fruits = %w[apple pear grape blueberry]
fruits.each do |f|
  puts f.length
end
#+end_src

In my Emacs:

Formatted Ruby code in Org Formatted Ruby code in Org

In the PDF:

Nicely formatted code from the PDF Nicely formatted code from the PDF

That also looks good!

It has the left line by the document setting, but the style is overridden in just this block to be the Pygments default, and for fun the font size is a bit smaller.

To make all this work I need Pygments installed, because that’s how minted does the formatting. That’s a simple external requirement (well, as simple as Python packages are; I use them so rarely I always get confused by whether I should use pip or pip3 and if it needs to be run as root, but the error messages are helpful and I get it right soon enough). But because it’s external, pdflatex needs to be run specially to allow an outside call:

pdflatex -shell-escape filename.tex

Or better yet this, to plough through problems:

pdflatex -shell-escape -interaction=nonstopmode filename.tex

I could configure Org to handle that but I’d rather do it by hand when needed and I know it’s safe.

Lastly, to show off the LaTeX fragment previews in Org, here’s some math almost plain (some of the raw LaTeX is prettified in the buffer) and then previewed. This is Org showing me in Emacs what the PDF output will look like.

Formula for pi in mostly raw LaTeX Formula for pi in mostly raw LaTeX
Formula for pi looking spiffy Formula for pi looking spiffy

I’m happy to have found one more way for Org and LaTeX to work together to make more beautiful documents.

UPDATE (22 November 2023): I rewrote this to use the toggle function instead of accidentally leaving the minted settings permanently on.

-1:-- Exporting Org source code blocks to LaTeX with minted (Post William Denton)--L0--C0--November 23, 2023 01:29 AM

Irreal: Zamansky: Learning Elisp #14

Mike Zamansky is back with the next chapter in his Learning Emacs video series. The most recent episodes considered writing a framework to replace certain keywords with an emoji. That started with code to simply replace the keyword with the emoji and moved on to using overlays to display the emoji in the display without altering the underlying text.

The current video considers how to make that code into a minor mode. That turns out to be pretty simple. There’s a macro that handles most of the details for you. You just fill in some parameters and everything else is taken care of.

This is a short video—only 8 minutes, 32 seconds—but Zamansky promises to expand on it in coming episodes. I’ve known—in a vague way—for a long time that making a minor mode was pretty easy but I didn’t realize until this video how simple it is. Once you’ve written the code to do whatever it is the mode is supposed to do, making it into a minor mode boils down to a simple macro call.

I’m looking forward to the future videos that flesh out the process a bit more. Even if you don’t want to publish your minor mode, it can still be useful for streamlining your local workflow. If you do want to share, the process is pretty easy.

-1:-- Zamansky: Learning Elisp #14 (Post jcs)--L0--C0--November 22, 2023 05:12 PM

Discovering Emacs podcast: Essential Movement and Editing Shortcuts in Emacs - EP5

-1:-- Essential Movement and Editing Shortcuts in Emacs - EP5 (Post Discovering Emacs)--L0--C0--November 22, 2023 12:20 AM

T. V. Raman: Announcing Emacspeak 59.0 (VirtualDog)

Announcing Emacspeak 59.0—VirtualDog!

Tilden

To express oneself well is impactful, but only when one has something impactful to express! (TVR on Conversational Interfaces)

1. For Immediate Release:

San Jose, CA, (November 22, 2023)

1.1. Emacspeak 59.0 (VirtualDog) Unleashed! 🦮

— Making Accessible Computing Effortless!

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 immediate world-wide availability of Emacspeak 58.0 (ErgoDog) 🦮 — a non-LLM powered audio desktop that leverages today's evolving Data, Social and Assistant-Oriented Internet cloud to enable working efficiently and effectively from anywhere!

2. Investors Note:

With several prominent tweeters (and mythical elephants) 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 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, remote software development, streaming media, social computing and electronic messaging into the audio desktop, Emacspeak enables spoken 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:

  1. Updated Keybindings ⌨
  2. Smart Buffer Selection ⛏
  3. Audio Volume Adjust 🔈
  4. Speech-Rate Adjust🚄
  5. Twitter Support Removed X marks the spot.
  6. BBC Sounds URL Template 📻
  7. BBC HLS Streams using MPV 📻
  8. ZOxide Integration ⏠ ⏡
  9. emacspeak-pipewire ǁ

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

Note: This version requires emacs-29.1 or later.

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 and the underlying GIT versioning software used to develop and distribute the system.

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 free of cost 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@emacspeak.net. 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 59 delivers better ergonomics by minimizing the need for chording, but sadly, with no dog to guide its way.
    • Emacspeak 58 delivers better ergonomics by minimizing the need for chording.
    • Emacspeak 57.0 is named in honor of Tilden Labrador.
    • Emacspeak 56.0 (AgileDog) belies its age to be as agile as Tilden.
    • Emacspeak 55.0 (CalmDog) attempts to be as calm as Tilden.
    • Emacspeak 54.0 (EZDog) learns to take it easy from Tilden.
    • Emacspeak 53.0 (EfficientDog) focuses on efficiency.
    • Emacspeak 52.0 (WorkAtHomeDog) makes working remotely a pleasurable experience.
    • Bigger 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 can't 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 Emacspeak Mail Archive –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, Aster, Hubbell and Tilden acknowledge their exclusive monopoly on setting the direction of the Emacspeak Audio Desktop (🦮) and promise to exercise their 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.

Author: T.V Raman

Created: 2023-11-18 Sat 07:56

Validate

-1:-- Announcing Emacspeak 59.0 (VirtualDog) (Post T. V. Raman (noreply@blogger.com))--L0--C0--November 21, 2023 08:14 PM

Mike Zamansky: Learning Elisp 14 - defining a minor mode

Another short one today. We're taking the code we already wrote and making a minor mode out of it.

In Emacs, a minor mode is a set of functionality that you can turn on (or off) in a buffer (or globally). For example, the built in auto-fill-mode can be turned on in a buffer will automatically add newlines when your line gets "too long." You can see the modes that you currently have on using the describe-mode function, usually bound to C-h m. I also currently have Hungry-Delete mode as well as Flyspell and a few others. Hungry-Delete automatically deletes multiple whitespace characters all at once so if I have five spaces between words, I can just delete or kill once and they'll all go away. Flyspell adds auto spell checking.

Minor modes can be turned on manually using M-x whatever-mode command which toggles whatever mode on and off or automatically based on hooks. For example, when you load a C file, I go into c mode which is a major mode (more about them some other time) as well as these minor modes:

  • Auto-Save
  • Corfu
  • Eglot–Managed
  • Eldoc
  • Flymake
  • Font-Lock
  • Hungry-Delete
  • Yas

Here's specific code we go over in the video to turn on and off our new mode:

(define-minor-mode emoji-replace-mode
 "fill in the docstring later"
 :lighter " ER"
 (if emoji-replace-mode
 (add-hook 'after-change-functions #'emoji-replace-insert nil t)
 (remove-hook 'after-change-functions #'emoji-replace-insert)))

The macro define-minor-mode does all the magic. The key is that it defines a "mode variable" - in this case named emoji-replace-mode which tells us if we're turning the mode on or off. Based on that, we either add or remove our hook. The :lighter " ER" sets what to show in the mode line.

We're just scratching the surface today - just setting up the basics. Later we'll see how to clean up the variables we need for the mode - specifically our list of emojis as well as how we can select either of our emoji replacement methods - overlay a text property or replace the text. We'll also see about setting up key combos for a mode in our next elisp project.

That's it for today.

Enjoy.

Code:

The code for the series is still up here:

-1:-- Learning Elisp 14 - defining a minor mode (Post)--L0--C0--November 21, 2023 06:47 PM

Irreal: Exiting Recursive Edits

Emacs Elements has an informative post on how to escape from a recursive edit. Unless you’re already an advanced user, you probably have only a vague notion of what a recursive edit is and you certainly aren’t going to be intentionally entering one. But, unfortunately, it’s fairly easy to stumble into one.

Even when you deliberately enter a recursive edit—the video has a typical use case—you still need to know how to exit to the main edit. The standard way to get out of a recursive edit is Ctrl+Alt+c but sometimes Emacs get wedged—especially when you inadvertently find yourself in a recursive edit—and you need to force an escape to the top level.

The video demonstrates several ways of doing this so you should definitely take a look but a good rule of thumb—although not a complete answer— is to try

  • Ctrl+g
  • Ctrl+]
  • Esc Esc Esc

in order.

There are, as I hinted, a few nuances so be sure to take a look at the video for the complete details. The video is only 8 minutes and 21 seconds so it should be easy to fit in.

Update [2023-11-23 Thu 11:41]: Existing → Exiting.

-1:-- Exiting Recursive Edits (Post jcs)--L0--C0--November 21, 2023 04:40 PM

Irreal: Editing LaTeX With Emacs

Michael Neuper has a very nice article on Efficient LaTeX Editing With Emacs. As far as I know, there’s only two reasonable ways of doing that:

  1. Org Mode
  2. AUCTeX

Org mode is good for what might be called “light weight” LaTeX. If there’s a minimum of mathematics and special formatting, Org is ideal. Its simple markup is easy to learn and you don’t to need to worry about the more difficult LaTeX syntax. The result is exported to LaTeX so you can add LaTeX formatting as needed and the resulting PDF is still produced by LaTeX so you get the beautiful typesetting that the TeX family promises.

If you need more heavy duty mathematics and formatting, it’s hard to beat AUCTeX. It is, after all, purpose built for writing LaTeX inside Emacs. Neuper concentrates on AUCTeX and shows how to augment it to obtain an efficient LaTeX writing environment.

For AUCTeX itself, he starts by showing how to get a live preview within Emacs. If you’re like me and like to see how the output of a long document is progressing as you write, this is a Godsend. A couple of keystrokes and the current document appears right there in a separate Emacs window. What could be better?

He also looks at using special symbols (in the LaTeX source) and folding. I don’t think those are as important as live preview but some may find them useful.

His next addition is CDLaTeX, which I’ve written about before. It provides some shortcuts for entering LaTeX commands and symbols. It’s also usable inside Org—or anywhere in Emacs, really—so it’s definitely worth knowing about if you write LaTeX, even in Org.

Next he looks at using LatexMK and LSP. Most TeX/LaTeX users know about using LatexMK to make sure forward references are resolved. I didn’t know there was as LSP engine for LaTeX but apparently there is. If you care about such things, Neuper shows you how to set it up.

Xenops is a package that I haven’t heard of before. It basically serves as a sort of in place replacement for live preview. Take a look at the animated GIF in Neuper’s post for a demonstration.

Finally, he considers YASnippet and Calc. Both of these are able to expand some simple text into more complicated LaTeX. The Calc example—also illustrated with an animated GIF—is especially revealing. I vaguely knew you could do this sort of thing but I’ve never seen it in action before. Very nice and very powerful.

If you write in LaTeX at all it’s definitely worth your while to take a look at Neuper’s post.

-1:-- Editing LaTeX With Emacs (Post jcs)--L0--C0--November 20, 2023 04:34 PM

Sacha Chua: 2023-11-20 Emacs news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, lobste.rs, kbin, programming.dev, lemmy, communick.news, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

-1:-- 2023-11-20 Emacs news (Post Sacha Chua)--L0--C0--November 20, 2023 04:24 PM

Eric MacAdie: 2023-11 Austin Emacs Meetup

There was another meeting a couple of weeks ago of EmacsATX, the Austin Emacs Meetup group. For this month we had no predetermined topic. However, as always, there were mentions of many modes, packages, technologies and websites, some of which I had never heard of before, and some of this may be of interest to ... Read more
-1:-- 2023-11 Austin Emacs Meetup (Post Eric MacAdie)--L0--C0--November 20, 2023 12:13 AM

Irreal: Ibuffer Filters

Ruslan Bekenev has a post on filtering the results of buffer listings that reminded me of something I’ve known since I started using Emacs but keep forgetting. Bekenev writes that he often lists the open buffers with Ctrl+x Ctrl+b mostly so that he clean up his Emacs environment by deleting no longer needed buffers. I used to do the same thing so I can sympathize with the urge.

One day, though, he wanted to filter the listing so that only buffers from his current project were listed. Sadly, list-buffers is pretty bare bones and doesn’t support filtering. Ibuffer does, though, and produces essentially the same output as list-buffers. My first thought was, “that’s neat” but I also felt that it seemed familiar.

It was, of course. Long ago when I first started using Emacs, I learned that I should use ibuffer instead of list-buffers. I last wrote about this only a year and a half ago but I’d already mostly forgotten how powerful ibuffer is. Every time I rediscover the filtering capability, I promise myself I’ll internalize and make regular use of it but the truth is I just don’t need filtering often enough for the habit to set.

In any event, ibuffer is a better version of list-buffers and well worth trying. As Mickey says in the above link, “You should switch to it right now.”

-1:-- Ibuffer Filters (Post jcs)--L0--C0--November 19, 2023 05:38 PM

Anything goes: Using use-package to bootstrap quelpa and quelpa-use-package

I use use-package and wanted to use it to bootstrap quelpa and loading quelpa-use-package. The project pages had instructions without use-package. Here is what I had to do.

(require 'package)
(setq package-archives
      '(("melpa" . "https://melpa.org/packages/"))
      use-package-always-ensure t)

(package-initialize)

(require 'use-package-ensure)

(use-package quelpa
  :ensure)

(use-package quelpa-use-package
  :demand
  :config
  (quelpa-use-package-activate-advice))

;; Now, you can take advantage of the :quelpa keyword.
(use-package copilot
  :quelpa (copilot :fetcher github
                   :repo "zerolfx/copilot.el"
                   :branch "main"
                   :files ("dist" "*.el"))
  :hook (prog-mode . copilot-mode)
  :bind (:map copilot-completion-map
              ("<tab>" . copilot-accept-completion)))

-1:-- Using use-package to bootstrap quelpa and quelpa-use-package (Post tsengf (noreply@blogger.com))--L0--C0--November 19, 2023 05:23 PM

Magnus: Making Emacs without terminal emulator a little more usable

After reading Andrey Listopadov's You don't need a terminal emulator (mentioned at Irreal too) I decided to give up on using Emacs as a terminal for my shell. In my experience Emacs simply isn't a very good terminal to run a shell in anyway. I removed the almost completely unused shell-pop from my configuration and the keybinding with a binding to async-shell-command. I'm keeping terminal-here in my config for the time being though.

I realised projectile didn't have a function for running it in the root of a project, so I wrote one heavily based on project-async-shell-command.

(defun mep-projectile-async-shell-command ()
  "Run `async-shell-command' in the current project's root directory."
  (declare (interactive-only async-shell-command))
  (interactive)
  (let ((default-directory (projectile-project-root)))
    (call-interactively #'async-shell-command)))

I quickly found that the completion offered by Emacs for shell-command and async-shell-command is far from as sophisticated as what I'm used to from Z shell. After a bit of searching I found emacs-bash-completion. Bash isn't my shell of choice, partly because I've found the completion to not be as good as in Z shell, but it's an improvement over what stock Emacs offers. The instructions in the repo was good, but had to be adjusted slightly:

(use-package bash-completion
  :straight (:host github
             :repo "szermatt/emacs-bash-completion")
  :config
  (add-hook 'shell-dynamic-complete-functions 'bash-completion-dynamic-complete))

I just wish I'll find a package offering completions reaching Z shell levels.

-1:-- Making Emacs without terminal emulator a little more usable (Post)--L0--C0--November 19, 2023 07:50 AM

Please note that planet.emacslife.com aggregates blogs, and blog authors might mention or link to nonfree things. To add a feed to this page, please e-mail the RSS or ATOM feed URL to sacha@sachachua.com . Thank you!