Fork me on GitHub
#emacs
<
2023-03-22
>
lassemaatta06:03:49

Anyone else having problems with running external programs from emacs when using emacsclient? E.g. doing a "As HTML file and open" export from org? Everything works fine with emacs .

lassemaatta06:03:51

I'm starting the server as a systemd service (https://www.emacswiki.org/emacs/EmacsAsDaemon#h5o-2) and it feels like it's missing some environmental variables or something like that

lassemaatta06:03:31

interesting. Running async-shell-command + firefox <some url> returns Error: no DISPLAY environment variable specified. And the same with xdg-open throws a xdg-open: no method available for opening '/home/lassemaatta/org-roam/20230321121039-<some file>.html' .

lassemaatta07:03:46

yeah, this looks more like a "systemd user services don't inherit the environment" issue rather than anything to do with emacs

jkxyz07:03:59

It may be because Emacs is starting before your X server. I think you can make it wait until graphical-session.target is reached, depending on your desktop environment. I switched to just starting Emacs in my sway config

lassemaatta07:03:22

yeah, the arch article describing systemd user services has a bunch of notes and workarounds relating to environment variables and how to pass them to the user services

jkxyz07:03:31

You don't necessarily need to convey all environment variables, just DISPLAY

jkxyz07:03:31

But I'm pretty sure those are all set by systemd when the service is launched as part of graphical-session.target

borkdude10:03:49

Argh, I'm frustrated by emacs lisp. How do I accomplish the following simple task? I want to write a clj! macro which sends its input expression to a process via stdin, and get the result back as a string. The rest I can figure out, but this part is confusing as hell.

(defmacro clj! (expr)
  (let* ((expr-as-string (prin1-to-string expr))
         (temp-buf "*el2clj-work*"))
    (get-buffer-create temp-buf)
    ???
    (shell-command-on-region (point-min) (point-max) "clj2el" temp-buf)
    ))

xificurC10:03:57

I got this from chatgpt, so no clue if it works, but the functions seem to exist 🙂

borkdude10:03:13

Got a solution already :)

👍 2
borkdude10:03:13

(see below)

borkdude10:03:40

Finally, a macro to transpile and evaluate the code:

(defmacro clj! (expr)
  (let* ((expr-as-string (prin1-to-string expr))
         (temp-buf "*el2clj-work*"))
    (get-buffer-create temp-buf)
    (let* ((elisp-code (with-current-buffer temp-buf
                         (erase-buffer)
                         (insert expr-as-string)
                         (shell-command-on-region (point-min) (point-max) "clj2el" temp-buf)
                         (buffer-substring (point-min) (point-max))))
           (read (read-from-string elisp-code))
           (expr (car read)))
      expr)))

(clj! (defn foo [x] (inc x)))
(foo 1) ;;=> 2

💯 6
borkdude10:03:37

This is a bit slow, but with a running server it could be faster and more feasible

borkdude10:03:52

(or with scimacs as the dynamic module in which the transpiler is doing its work... it's already fast)

2
borkdude11:03:47

@U3X7174KS

(clj! (progn (defn foo [x] (inc x))
             (defn bar [x] (inc x))
             (foo (bar 3)))) ;; => 5

💯 2
teodorlu11:03:17

Nice! I tried making a macro yesterday, but wasn't able to make it work.

teodorlu11:03:32

> (or with scimacs as the dynamic module in which the transpiler is doing its work... it's already fast) Yes - avoiding the process startup/shutdown overhead would be best. But this is a good start!

teodorlu11:03:03

I'm not 100 % sure about emacs lisp conventions, but in order to play nice with other Emacs code, we might consider prefixing all our public variables with the package name. In other words, consider using clj2el! or clj2el-clj! as names for the clj! macro.

borkdude11:03:05

Yes, did that in the repo now

borkdude13:03:57

Would this be a common sense translation for hash-maps?

(def m {:a 1}) ;;=> (setq m (list (list :a 1)))
 (:a m) ;;=> (cdr (assoc :a m))

vemv14:03:04

matching https://github.com/clojure-emacs/parseedn output seems a useful definition of 'common sense' :) https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html can also be a useful guide

Benjamin15:03:40

(assoc-default 'a `((a . ,(+ 1 1))))
2
Your m is not really an alist right now. The element is a list but should be a cons pair

ericdallo15:03:44

also, there may be case where you want it as a plist, not a hashmap (lsp-mode for example has a lsp-use-plists which increase performance and use plists instead of hash-maps for most things). Example of plist:

'(:foo 1 :bar 2)

borkdude16:03:05

aha, yes plist is maybe what I want

borkdude14:03:59

ah json also parses to hash-maps: (json-parse-string "{\"a\": 1}")