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:
(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
audio-player
.
Here is what I have tried:
("mkv" . video-player)
- gives
Wrong type argument: sequencep, video-player
("mkv" . 'video-player)
- gives
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?
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?
(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.
;; By quoting with ` instead of ' we can use the comma to unquote our variables
(setq dired-open-extensions `(("mkv" . ,video-player) ) ) )
Hello,
for the
("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
( ("mkv" "mp4") . ,video-player)
?
( ("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?
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:
(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
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
(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)