Das s-lex-Format von sel ist genau das, was Sie wollen, aber wenn Sie in der Lage sein möchten, Code in die Substitutionsblöcke und nicht nur in Variablennamen einzufügen, habe ich dies als Proof of Concept geschrieben.
(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."
Sie können sogar einen fmt
Anruf in einen anderen einbetten, fmt
wenn Sie verrückt sind
(fmt "#{(fmt\"#{(fmt\\\"#{user-full-name}\\\")}\")}")
;; =>
"Jordon Biondo"
Der Code wird nur zu einem format
Aufruf erweitert, sodass alle Ersetzungen der Reihe nach ausgeführt und zur Laufzeit ausgewertet werden.
(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)))
Es könnte verbessert werden, welcher Formattyp verwendet wird, anstatt immer% s zu verwenden. Dies müsste jedoch zur Laufzeit erfolgen und würde zusätzlichen Aufwand verursachen. Dies könnte jedoch dadurch erreicht werden, dass alle Formatierungsargumente in einem Funktionsaufruf zusammengefasst werden, der die Dinge gut formatiert on type aber wirklich das einzige szenario, in dem du das willst, ist wahrscheinlich floats und du könntest sogar ein (format "% f" float) in der ersetzung machen, du warst verzweifelt.
Wenn ich mehr dran arbeite, aktualisiere ich eher diesen Kern als diese Antwort. https://gist.github.com/jordonbiondo/c4e22b4289be130bc59b