Le format s-lex de s.el est vraiment ce que vous voulez, mais si vous voulez réellement pouvoir mettre du code à l'intérieur des blocs de substitution et pas seulement des noms de variables, j'ai écrit cela comme une preuve de concept.
(defmacro fmt (str)
"Elisp string interpolation for any expression."
(let ((exprs nil))
(with-temp-buffer
(insert str)
(goto-char 1)
(while (re-search-forward "#{" nil t 1)
(let ((here (point))
(emptyp (eql (char-after) ?})))
(unless emptyp (push (read (buffer-substring (point) (progn (forward-sexp 1) (point)))) exprs))
(delete-region (- here 2) (progn (search-forward "}") (point)))
(unless emptyp (insert "%s"))
(ignore-errors (forward-char 1))))
(append (list 'format (buffer-string)) (reverse exprs)))))
;; demo with variable and code substitution
(fmt "My name is #{user-full-name}, I am running Emacs #{(if (display-graphic-p) \"with a GUI\" \"in a terminal\")}.")
;; results in
"My name is Jordon Biondo, I am running Emacs with a GUI."
Vous pouvez même intégrer un fmt
appel dans un autre fmt
si vous êtes fou
(fmt "#{(fmt\"#{(fmt\\\"#{user-full-name}\\\")}\")}")
;; =>
"Jordon Biondo"
Le code se développe simplement en un format
appel afin que toutes les substitutions soient effectuées dans l'ordre et évaluées au moment de l'exécution.
(cl-prettyexpand '(fmt "Hello, I'm running Emacs #{emacs-version} on a #{system-type} machine with #{(length (window-list))} open windows."))
;; expands to
(format "Hello, I'm running Emacs %s on a %s machine with %s open windows."
emacs-version
system-type
(length (window-list)))
Des améliorations pourraient être apportées au type de format utilisé au lieu de toujours utiliser% s, mais cela devrait être fait au moment de l'exécution et ajouterait des frais généraux, mais cela pourrait être fait en entourant tous les arguments de format dans un appel de fonction qui formate joliment les choses en fonction de la base sur le type mais vraiment le seul scénario où vous voudriez que ce soit probablement des flottants et vous pourriez même faire un (format "% f" flottant) dans la substitution est que vous étiez désespéré.
Si j'y travaille plus, je suis plus susceptible de mettre à jour cet essentiel au lieu de cette réponse. https://gist.github.com/jordonbiondo/c4e22b4289be130bc59b