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.
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.
like this
@Simon Brooke What I was looking to do was to call concat with the list returned by (my-function arg1 arg2) used as arguments.
As it turns out, all the functionality I was looking for was already supplied by the string-join function. I just didn't know it existed.
(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
like this
FOSS Dev reshared this.
#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
No no, the obarray you see from elisp is the same one used by the reader. Elisp is an old-style Lisp here, and the obarray is a first-class thing: you can make a new one, rebind obarray, etc.
That's the sort of thing people don't do much anymore, but used to do. The documentation covers it reasonably well gnu.org/software/emacs/manual/β¦
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"))))))
That's awesome. I need to hear my own advice, of course, but don't be inhibited to share something that isn't finished. It's the Fediverse! We're all anarchists! The kind sort, I mean.
Lisp macros are just so powerful.
Wait, how do you get the awesome code formatting? Anybody know how to configure this on fediscience.org?
AM I GOING TO HAVE TO SPIN UP MY OWN INSTANCE AGAIN
@James Endres Howell Frendica has a markdown add-on.
I just typed:
```lisp
...code...
```Typing that however was trickier.
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.
like this
@Γ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.
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
vim guy here. happy to see I inspire others...
May be you could post on our forum. Not sure you will get more users, though
@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.
May be you didn't see you that you can generate an interactive HTML output, on the site.
That was designed for people who don't want to print.
Should I make it more visible?
format to use a thousands separator? That'd be nifty, but it doesn't look like there is a way.
The original keyboards used long ago had Ctrl, Super, Hyper, Meta, and ALT keys. We now map Meta (i.e. ESC) to the Alt key on our keyboards as a convenience. I do not believe there is a way, on modern keyboards, to have both META and ALT mapped to a key. We can have Super, and Meta. I can't recall if I was able to map Hyper on a modern keyboard.
Jonathan Lamothe likes this.
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?
like this
Wes reshared this.
Define key is my least favorite way to make a keymap.
I like defvar-keymap, bind-keys, if you've got a map create already. Like a sparce map.
General is nice too. But then you have to have that installed.
Jonathan Lamothe likes this.
@Zenie That's an option, but my concern is that the reason they might be vague in the docs is because the specific error might change in future versions.
Perhaps I'm just being overly paranoid.
Usually errors are obvious and for very specific reasons. You can just catch them and print the message so if anything does change you will know.
I don't think it's worth worrying about.
reshared this
Just spent a good half hour pulling my hair out trying to figure out why one of the #elisp functions I had just written was always returning nil when I tested it. Turns out, my test was mistakenly passing its inputs to the wrong (but similarly named) function (pivot-table-get-columns instead of pivot-table-get-body).
#Haskell's type system would've caught this. π
C's type system would also have caught it, and it isn't worth a hill of beans.
By caught it what do we mean? This is not a case of some undetected error escaping your attention due to dynamic typing. You know you got a nil which is unexpected and wrong. It's in a test case which catches it.
The only thing a type system would change is that you would instead waste a half hour not understanding how your obviously correct function call can possibly have the wrong return type.
nil is about the least useful failure state there is.
@Alessio Vanni Yeah, it's just very magic number-ey.
Ah well, such is the way it is with legacy code sometimes. No way to change it without breaking about a billion other things.
Marco Antoniotti
in reply to Jonathan Lamothe • • •Sensitive content
Jonathan Lamothe
in reply to Marco Antoniotti • •would yield:
"foo: 1, bar: 2, baz: 3"Holger
in reply to Jonathan Lamothe • • •Sensitive content
gnu.org
www.gnu.orgJonathan Lamothe
in reply to Holger • •pcase.Marco Antoniotti
in reply to Jonathan Lamothe • • •Sensitive content
Marco Antoniotti
in reply to Holger • • •Sensitive content
Marco Antoniotti
in reply to Jonathan Lamothe • • •Sensitive content
*** Welcome to IELM *** Type (describe-mode) or press C-h m for help.
ELISP> (cl-multiple-value-bind (foo bar baz)
(apply #'cl-values (list 1 2 3))
(list baz bar foo))
(3 2 1)
```
Marco Antoniotti
in reply to Marco Antoniotti • • •Sensitive content
.... or:
`
ELISP> (cl-destructuring-bind (a s &key (foo 42) bar)
(list 1 2 :bar 666)
(list bar foo s a))
(666 42 2 1)
`
Jonathan Lamothe
in reply to Jonathan Lamothe • •My guess is that maybe
pcasecan do something similar?pcaseconfuses me.Weekend Editor
in reply to Jonathan Lamothe • • •Sensitive content
Doesn't destructuring-bind do something along these lines, if not exactly this?
(Assuming you meant Common Lisp. If it's Emacs lisp, then I dunno.)
Jonathan Lamothe
in reply to Weekend Editor • •pcase.Thuna
in reply to Jonathan Lamothe • • •Sensitive content
Jonathan Lamothe
in reply to Thuna • •seq-leta lot better.