So I'm working on an #OrgMode document that's probably about 2/3 #emacs #lisp code. I'm planning on releasing it shortly, but I'm not sure what to do about the licensing. Normally I use the #AGPL for my code, but since this isn't strictly code, I'm wondering if some version of the #CreativeCommons license might be a better fit. Do they have a #copyleft variant?
in reply to Jonathan Lamothe

CC-BY-SA is Creative Commons' answer to copyleft. CC-BY-SA-4.0 is one-way compatible into GPLv3. (The 4.0 is important!)

There's no CC license that forces code all the way to AGPLv3, but you can say "code blocks AGPLv3, the rest CC-BY-SA-4.0." You have to choose whether a single license or the Affero clause matters more.

Just spent a day and a half hunting down a bug that was making me question my sanity. As it turns out, #emacs #lisp's / function silently drops the decimal in its result if both of its inputs are integers... so (/ 1 2) evaluates to 0, not 0.5. Granted, this is also the way that C does it, but in my defense, #CommonLisp does not do this.
in reply to Jonathan Lamothe

As a first approximation, I suggest thinking of Emacs Lisp as closer to MacLisp than to Common Lisp.

A precise description of "closer" would be fairly long.
For example, Emacs Lisp acquired things like bignums and lexical bindings fairly late.

Again as an approximation, the descendancies are:
MacLisp → Emacs Lisp
MacLisp and others → Common Lisp
(Those others include, in alphabetical order, Interlisp, Scheme, Zeta Lisp, etc., but not Emacs Lisp.)

And then an important aspect of these approximations is the `cl' package, also a late addition that evolved quite a bit.

Transferring knowledge about C to Emacs Lisp is rather tricky, even though the implementation of a part of Emacs (including the Emacs Lisp virtual machine) is written in C.

#CommonLisp
#Elisp
#Emacs
#EmacsLisp

@me

in reply to Jonathan Lamothe

yup of course, but that's integer math, not floating point math

GNU Clisp and SBCL don't show decimals for integer division, but return fractions instead!

* (/ 1 2)
1/2

But of course if you use floating point representation for the parameters then the result is a floating point number as expected:
[1]> (/ 1.0 2.0)
0.5

Elisp, with floating point parameters, also works as expected:
(/ 1.0 2.0)
0.5

In C, with IEEE 754 double values, then 1.0/2.0 = 0.50, exactly, no rounding or epsilon comparison needed.

Spent several hours today trying to figure out why my #elisp code was misbehaving. Turns out, I made a mistake while trying to be clever. Instead of doing:

(when (and cond1 cond2)
  stuff
  ...)

I did:
(and cond1 cond2
  stuff
  ...)

...which would only work if every instruction in stuff returned a non-nil value.

I should stop trying to be clever.

#emacs

Edit: when, not while

Dave Marquardt reshared this.

in reply to Jonathan Lamothe

For the morbidly curious, this is the (now corrected) code:
(defun jrl-collect-data (table input output)
  "Collect table data into lists of outputs per input"
  (let (res record in-val out-val collection)
    (while table
      (setq record (car table)
            in-val (assoc input record)
            out-val (assoc output record))
      (when (and in-val out-val)
        (pop in-val)
        (pop out-val)
        (setq collection (assoc in-val res))
        (if collection
            (push out-val (cdr collection))
          (push (list in-val out-val) res)))
      (pop table))
    res))

I should probably throw some comments in here, but essentially the assoc in the when block always returns nil on the first iteration of the loop, and if it can't progress past that point, it'll always return nil on subsequent loops and nothing will ever happen. As a result, any list I might feed into this function is always going to result in a nil output.

So, I think I might be a nerd.

@SDF.ORG is running a BBS called bitzone. On this BBS they have a door game called LORD (League of the Rare Dragoon (not to be confused with Legend of the Red Dragon, of which it is clearly a knock-off)).

The fact that I'm playing this game in the first place is kind of nerdy, but wait, there's more.

In said game you have a character with various stats. One of these stats is "charm", which seems to get you discounts in the shops. Unfortunately, there's nothing to say exactly how this relationship works. So I've decided to try to reverse-engineer it with #emacs #org-mode.

I've created a table to track my purchases. It tracks my charm at the time of purchase, the list price for the item, and the price I actually paid. There's also an additional colum that calculates the actual discount, but that's trivial.

Anyhoot, I'm adding some code to this file that reads the values in the table and computes the simplest polynomial function that satisfies the equation:
$$price_{actual}=f(charm,price_{list})$$

This is done with the aim of predicting how much I'd actually spend on an item before actually buying it. It of course assumes that the equation being used is a polynomial equation, but I'm hoping it'll at least be able to approximate with a large enough set of data points.

Am I doing this because it's reasonable?

No.

I'm doing it because it's an interesting challenge... and I'm a nerd.

CC: @tob

in reply to Jonathan Lamothe

So it occurs to me that the approach I was considering is probably not going to work for a couple reasons:

  1. I thought the technique I use for curve fitting a single input function could be adapted to multi-dimensional functions. I realize now that it can't (at least not in the way I was thinking).
  2. Even if I do sonetning like calculating the discount value based on the list price and actual price and fitting a curve between that and the charisma stat, the discount is going to have to be constrained within a range between zero and the list price. A polynomial function with a finite series of terms just isn't going to be able to cut it.

I'll continue collecting data to see if any patterns start to emerge, though.

I've been using #Emacs's #Gnus for news/mail/RSS, but for whatever reason it's having trouble subscribing to ATOM feeds (RSS is fine). I seem to be missing the nnatom backend. Is there something special I need to do to add it?
#AskFedi

reshared this

in reply to Jonathan Lamothe

Over the weekend I was messing around with ibuffer, integrating my custom ibuffer groups with @sanityinc's ibuffer-vc (recommended).

I was surprised to discover that documentation for ibuffer (in since 22.1?) is ... sparsely documented. But it was fun to get it working because the code (and Steve's add-on) is

PERFECTLY LIMPID

(the real story here is that I have been waiting a lifetime to drop the phrase "perfectly limpid" for internet points and here is my opportunity)

github.com/purcell/ibuffer-vc

#emacs #ibuffer

This entry was edited (Monday, April 13, 2026, 1:00 AM)

James Endres Howell reshared this.

in reply to James Endres Howell

in reply to Daniel Mendler

@minad My annoyance with ibuffer:

The filter groups are defined as a list (of lists), which (per the definition of list) has an order.

That order determines the logic of which buffers get assigned to which groups. That order also determines the order in which those groups get displayed.

Sometimes I want those orderings to be different. Which would require two lists.

Each element already has a name string, so a display-order list could reference elements in the filter-order list. But that gets complicated when some of the elements are generated dynamically, like from ibuffer-vc.

This annoyance is probably not worthy of the effort to rewrite the package with a different abstraction. Especially not the effort to do so without introducing breaking changes.

@me @sanityinc

in reply to James Endres Howell

in reply to Bharath M. Palavalli

@bmp @jameshowell @sanityinc Yes, bufler looks nice! Alphapapa has many great packages. But I have slightly different preferences regarding dependencies and library usage. In addition to bufler I would have to install these libraries: burly, dash, f, hydra, lv, pretty-hydra and s. This is pretty large footprint. I care about this for multiple reasons - supply chain issues and consistency on the Elisp level. To be clear, this should not matter much for most users.
in reply to Daniel Mendler

@bmp @jameshowell @sanityinc @pkal I am by no means a package minimalist - I have many packages installed and I suggest that people take advantage of our large ecosystem. However I differentiate between packages on the user level and the library level. On the library level my preference is to rely on Emacs builtins for basic functionality (instead of dash, f or s). If crucial library functionality is missing it can be added to subr.el and then ported back via Compat.
in reply to Daniel Mendler

@bmp @jameshowell @sanityinc @pkal Unfortunately it turns out that adding new functionality to subr.el sometimes leads to long emacs-devel discussions with little progress. Not all additions are not welcome, like the recently discussed file-to-string function. These are the gaps which are then filled by libraries like dash, f or s.
in reply to Daniel Mendler

Agreed. I think the point to stress here is that users can decide. Hydra, for example, always struck me as relatively bloated, buggy, and a little too idiosyncratic with respect to (at least my mental models of) Emacs internal and UI conventions. But obviously it was very popular! Let a thousand flowers bloom. Cherish the Four Freedoms 😀

@bmp @me @sanityinc @pkal

This entry was edited (Tuesday, April 14, 2026, 1:28 PM)
in reply to James Endres Howell

@jameshowell Actually I found Hydra pretty good and simple. It is a smaller variant of Transient. But given that Transient is now the standard why not rely on it? I agree with you that users should decide and I want to emphasize that on the user level the underlying libraries do not matter.
@bmp @me @sanityinc @pkal
in reply to Daniel Mendler

@minad @jameshowell @sanityinc @pkal I haven’t gotten to the point of discerning between packages based on such criteria:-), I’ve been relying on packages that help provide the functionality I need. Maybe, sometime in the future I’ll start a screening process before I use them!
in reply to Jonathan Lamothe

I have the same issue with @Tutanota : my emails never make it to some recipients. I’ve never sent a single spam on my life. The only factor I was able to isolate is that anything going to Gmail or a Google-managed address doesn’t make it, which I assume means it was caught in some spam filters. But it’s not the only factor. I just haven’t figured out what makes it so I can’t write to some other addresses.

It’s really a PITA, forcing me to keep another email.

@Tuta
This entry was edited (Monday, April 13, 2026, 7:12 PM)
in reply to Celeste Ryder 🐾 🐀🏳️‍🌈

@Celeste Ryder 🐾 🐀🏳️‍🌈 @Tuta The weird thing is that it works if I use any other client. I'm still trying to figure out what the problem is. When I find it in my spam box and I click "why is this marked as spam" it says that it's there because it resembles other messages that have been marked as spam.

In other words: we put it in spam because we thought it looked like spam, which is... unhelpful.

Is there a way in #emacs #org-mode to next quote blocks? The following doesn't seem to work.

#+begin_quote
This is a quote.

#+begin_quote
This is a quote within the quote.
#+end_quote
#+end_quote

Emacs is ignoreing the second #+begin_quote and just closing the quote block at the first #+end_quote.

Edit: So the solution I settled on was putting the nested quote in a drawer named :quote:. it's not an ideal solution, but for my purposes in this case it's... fine, I guess.

God help me if I ever need three levels of nesting.

Does anyone happen to know if there's an easy way to get #emacs's nov.el package to display text using the #OpenDyslexic font? I was hoping there was a customization variable, but it seems not.

Perhaps I could run it in a terminal editor and change the terminal's font, but then I'd lose things like images.

I can hack something together if I really need to, I'd just rather not if there's a simpler solution available.

#a11y #books

Edit: I was able to do this through M-x customize-face

reshared this

in reply to Jonathan Lamothe

The media in this post is not displayed to visitors. To view it, please go to the original post.

As it happens, I was changing font on #Emacs just yesterday. M-x menu-set-font will open a font browser and let you choose, and it works. You can also select this from the 'Options' menu.

This however isn't 'sticky' -- next time you start emacs it will have reverted.

I found that

(set-frame-font "OpenDyslexic")

in my init.el works to change it persistently.

emacs problems

So, I've started a new job. In said job, I'm editing a document which I've spent a couple hours working on. This is all being done in a browser.

I reach a point where I want to search backward through the text for a name, so my #emacs brain says, "Easy peasey, that's just C-r", which I press... reloading the page.

It's at this point I have a minor heart attack, and consider myself lucky that their web app frequently saves my work.

elisp
God, my tab completion function is a hacky mess:
(defun lambdamoo-tab-complete ()
  "Complete user input using text from the buffer"
  (interactive)
  (when (memq (char-before) '(?  ?\r ?\n ?\t ?\v))
    (user-error "Point must follow non-whitespace character"))
  (let (replace-start
        (replace-end (point))
        replace-text found-pos found-text)
    (save-excursion
      (backward-word)
      (setq replace-start (point)
            replace-text (buffer-substring replace-start replace-end))
      (when (or (null lambdamoo--search-text)
                (not (string-prefix-p lambdamoo--search-text replace-text t)))
        (setq-local lambdamoo--search-text replace-text)
        (set-marker lambdamoo--found-point (point)))
      (goto-char lambdamoo--found-point)
      (unless
          (setq found-pos
                (re-search-backward
                 (concat "\\b" (regexp-quote lambdamoo--search-text))
                 (point-min) t))
        (setq-local lambdamoo--found-point (make-marker))
        (user-error "No match found"))
      (set-marker lambdamoo--found-point found-pos)
      (forward-word)
      (setq found-text (buffer-substring found-pos (point))))
    (delete-region replace-start replace-end)
    (insert found-text)))

#emacs #lisp #moo #mud #LambdaMOO

reshared this

elisp question

I'm certain I have reinvented a wheel here, but for the life of me I can't find it. Have I?

(defmacro jrl-extract-list (vars list &rest body)
  "Split a list into indiviual variables"
  (let ((list* (gensym)))
    (append
     `(let ,(cons (list list* list) vars))
     (seq-map (lambda (var)
                `(setq ,var (car ,list*)
                       ,list* (cdr ,list*)))
              vars)
     body)))

#emacs #lisp #elisp

Edit: Of course it was pcase.

elisp question

I just put a call to eval in my code and I feel dirty now.

The context went something like this:

(eval (cons 'concat (my-function arg1 arg2)))

I had initially hoped to use
(concat . (my-function arg1 arg2))

...but this resulted in a call to
(concat my-function arg1 arg2)

Which was not what I expected.

Is there a better way I could've written this?
#emacs #lisp #elisp

Edit: Got my answer. I wanted:

(apply 'concat (my-func arg1 arg2))

Edit 2:
It turns out the code I really wanted was:

(string-join arg2 arg1)

I love reinventing the wheel because I didn't know it was already there.

Edit 3:
Here's the actual code:

(defun lambdamoo-run-text-replacements (str)
  "Perform text replacements on the string"
  (dolist (vals lambdamoo-text-replacements)
    (let* ((from (car vals))
           (to (cdr vals))
           (split (split-string str from)))
      (setq str (string-join split to))))
  str)

Let's see if there's anything else I've reinvented here.

I just wrote a bunch of #elisp code like this:
(catch :abort
  ;; do something
  (when condition
    (message "A bad thing happened")
    (throw :abort nil))
  ;; do something else
  )

When the functionality I really wanted was:
(progn
  ;; do something
  (when condition
    (user-error "A bad thing happened"))
  ;; do something else
  )

I knew the former felt sketchy, but I couldn't think of a better way to do it until just now.
#emacs #lisp

#Elisp logic:

All interned symbols can be found in a lookup table. This table is bound to the obarray symbol.

Hang on a minute...

I can only assume that the underlying C code has its own pointer to this table and the obarray symbol is only provided as a convenience for elisp functions that can't see this pointer?
#emacs #lisp

in reply to James Endres Howell

@James Endres Howell
I'm a little self-conscious about it as non-trivial is relative, but...
(defmacro lambdamoo-chatter-interact
    (func-name to msg docstring fmtstr &rest vals)
  "Define a function for interacting with another player"
  (let ((proc (gensym))
        (str (gensym)))
    `(defun ,func-name (,proc ,str)
       ,docstring
       (let ((,to lambdamoo-chatter)
             (,msg (substring-no-properties (lambdamoo-command-text ,str))))
         (if ,to
             (funcall lambdamoo-send-line ,proc
                      (format ,fmtstr . ,vals))
           (message "No chatter specified"))))))

I am dangerously close to unleashing my first #emacs package on the public. It's nothing fancy and still relatively niche, but I deem it potentially useful enough to be worth publishing.

There are a couple small features I want to add and a few things that still need some polish, but it's almost ready for a version 0.1 release.

It's not anything ground breaking or anything. I'm still pretty much an #elisp novice, but I'm proud of it anyway.

More details when it's released.

in reply to Álvaro R.

@Álvaro R. At this point all I need to add is a README and two features (which will mostly reuse code I've already written just in a slightly different way).

Surprisingly enough, the hardest part of the whole project was getting it to display numbers with thousands separators. That code might exist in the bowels of the calc package, but it was easier to just roll my own.

in reply to Jonathan Lamothe

Okay, my first #Emacs package is officially released. It was strongly inspired by @Soroban Exam Website's work, providing practice tools for the #soroban. This is the first Emacs package I've ever released. It's probably not perfect, but I welcome feedback on how it can be improved.

I wonder if there is an overlap of more than say five people who are both soroban and emacs users. 🙃

Anyhow, it can be found at: codeberg.org/jlamothe/soroban

reshared this

in reply to Soroban Exam Website

@Soroban Exam Website Might as well. I wrote it mainly for myself, partly because I don't own a printer and this makes it easier to practice when working from a computer screen, but also just to see if I could.

Still, if someone else is going to find it useful, that's probably the place I'll find them.

elisp nonsense

I've been playing around with keymaps. Apparently they can be used to create menus that give the user a visual list of options. The canonical way to make them is aparently with make-sparse-keymap to create the menu and define-key to add options to it, but this causes some confusing behaviour.

Take the following example:

(let ((menu (make-sparse-keymap "My menu")))
  (define-key menu "a"
    '(menu-item "Foo" foo))
  (define-key menu "b"
    '(menu-item "Bar" bar))
  menu)

Yields the following:
(keymap (98 menu-item "Bar" bar) (97 menu-item "Foo" foo) "My menu")

Each new entry is added to the top of the list, so when the menu is displayed, they're listed in reverse order. This is very counter intuitive.

Now, I understand that the nature of lists in lisp make inserting an element at the top of the list less computationally expensive, but when you've already got to walk the whole list anyway to ensure the key binding isn't already present, this no longer feels like an adequate excuse.

Am I missing something?

#emacs #elisp

Wes reshared this.

I virtually never set custom keybindings in #Emacs preferring instead to rely on M-x function calls because I had such a hard time finding key sequences that weren't used by something else. Since learning that C-c /[A-Za-z]/ is reserved for user-defined keybindings, I've gone mad with power.

reshared this

Long-winded post about Emacs and gripe about modern computing

I think I've been able to pin down what it is that I like about #Emacs so much. When I first started using computers, I was using a TRS-80. If you didn't have a cartridge inserted, It'd boot directly into BASIC where you could program the machine directly. That wasn't a bug, it was a feature.

Modern computing seems to do its best to hide all that stuff away. Everything is treated more like a simple (albeit specialized) appliance, not a powerful machine that can be made to do literally anything you want. Instead, it's about what the various software vendors want it to do.

Emacs by contrast not only gives you all the tools you need to modify it in any way you want, but actively encourages you to do so. It feels a lot more like the computing systems of old. Perhaps that's not for everyone. There's a reason computers were so niche back in the early days. Most people just didn't care to learn what was going on under the hood, and that's valid. There's something to be said for a tool that just works effortlessly out of the box. Also, to be clear, you don't strictly speaking need to dig into the internals to use Emacs, but I prefer for my technology to serve me, and I'm willing to put the effort in to make that happen.

That's why it's a good fit for me.

in reply to Jonathan Lamothe

You could try package-build-create-recipe
It will need to be filled in, but if your headers are correct, with author, packages-required, version, etc.

Edit the recipe for your git. You'll be in recipe mode.
Saving it puts it in .../elpa/recipes/
Building it with C-c C-c will make a package and install it in your elpa..

That might teach you what you need.

It will automatically pick up .el and .texi files.
Not eld, but if you have some odd file, you can add the pattern to the recipe. I have an eld which is not in the list of automatic files.

See the contributing doc at GitHub Melpa.

in reply to Jonathan Lamothe

Per the help doc for org-agenda

"If the current buffer is in Org mode and visiting a file, you can also
first press ‘<’ once to indicate that the agenda should be temporarily
(until the next use of ‘SPC o a’) restricted to the current file.
Pressing ‘<’ twice means to restrict to the current subtree or region
(if active).
"

In other words, execute org-agenda then press "<" before the command you want to run against the agenda.

This entry was edited (Saturday, August 30, 2025, 7:19 PM)

This website uses cookies. If you continue browsing this website, you agree to the usage of cookies.