Skip to main content
Topic: Help with emacs-lisp programming (Read 419 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Help with emacs-lisp programming

Hello everyone!
Lately I have gotten around to rewriting my Emacs config. I basically merged my old one with what DistroTube "Configuring Emacs" series, of course with changes.

Here is the problematic code snippet:

Code: [Select]
(use-package dired-open
    :config
    (setq dired-open-extensions '(
                                  ;; Images
                                  ("jpg"  . "okular")
                                  ("png"  . "okular")
                                  ("webp" . "okular")
                                  ;; Video
                                  ("mkv"  . "mpv")
                                  ("mp4"  . "mpv")
                                  ;; Audio
                                  ("flac" . "mpv")
                                  )
          )
    )
As you can see there is a lot of repetition, so I wanted to make it so that I have three variables image-viewer, video-player and
Code: [Select]
audio-player
.

Here is what I have tried:
Code: [Select]
("mkv"  . video-player)
- gives
Code: [Select]
Wrong type argument: sequencep, video-player
Code: [Select]
("mkv"  . 'video-player)
- gives
Code: [Select]
Wrong type argument: characterp quote

I have also tried setting the variable with defvar and setq. None of them worked.

Do any of you know how to do this properly?

Re: Help with emacs-lisp programming

Reply #1
Code: [Select]
("mkv"  . video-player)
Code: [Select]
("mkv"  . 'video-player)

When you're quoting the whole alist (that's what the ' does before the beginning open parenthesis) it will be returned unevaluated. So for the first one "video-player" is being interpreted as an array (literally the characters v, i, d.. and so on) while the second is the phrase "video-player" quoted again.

I can think of two solutions. First - will it accept this syntax?

Code: [Select]
(use-package dired-open
    :config
    (setq dired-open-extensions '(
               ("jpg" "png" "webp"  . "okular")
               ("mkv" "mp4" "flac"  . "mpv"))
    )
 )

If not, you probably need a backquote instead of a regular quote. Indicated with a ` (backtick) rather than a ' (single quote) the backquote will allow you to unquote some things such as variables when you don't want them to be read literally.

Code: [Select]
    ;; By quoting with ` instead of ' we can use the comma to unquote our variables
    (setq dired-open-extensions `(("mkv"  . ,video-player) ) ) )

Re: Help with emacs-lisp programming

Reply #2
Hello,
for the
Code: [Select]
("mkv" "mp4" . "mpv")
solution the error message was: Wrong type argument: listp "mpv".

The second solution works well! Thank you!


Now I am thinking how to condense this even more.
Is there a possibility to do something like 
Code: [Select]
( ("mkv" "mp4") . ,video-player)
?

Re: Help with emacs-lisp programming

Reply #3
Code: [Select]
( ("mkv" "mp4") . ,video-player)

That's actually how I should have typed it the first time - with the file extensions in a list, sorry my fault. Does it give you an error?

Re: Help with emacs-lisp programming

Reply #4
Yes, it produces an error;

( ("mkv" "mp4") . ,video-player) -- Wrong type argument: stringp, ("mkv" "mp4")
( '("mkv" "mp4") . ,video-player) -- Wrong type argument: stringp, '("mkv" "mp4")
( "mkv" "mp4" . ,video-player) -- Wrong type argument: listp "mkv"

I have tried messing around with mapcar:
Code: [Select]
(defconst video-extensions '( "mkv" "mp4" ) "Video file extensions")
(setq dired-open-extensions `(,@(mapcar (lambda (format) (list format . video-player)) video-extensions))
But it gives the wrong type argument: stringp error.
Without the ' around the inner list in defconst it does not compile at all

I am not sure what to do

 

Re: Help with emacs-lisp programming

Reply #5
You likely need to unquote the individual variables, not the final list, but I think you're making it too hard on yourself

The below evaluates ok for me
Code: [Select]
(use-package dired-open
  :config
  (let ((video-ext '("mkv" "mp4"))
        (image-ext '("jpg" "png" "webp"))
        (audio-ext "flac")
        (video-player "mpv")
        (image-viewer "okular"))
    (setq dired-open-extensions
          `((,video-ext . ,video-player)
            (,image-ext . ,image-viewer)))))

You can use constants if you prefer them to "let," I just like let for lexical binding (which is a whole different thing)