Định dạng s-lex của s.el thực sự là những gì bạn muốn, nhưng nếu bạn thực sự muốn có thể đặt mã bên trong các khối thay thế và không chỉ là tên biến, tôi đã viết nó như một bằng chứng về khái niệm.
(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."
Bạn thậm chí có thể nhúng một fmt
cuộc gọi bên trong một cuộc gọi khác fmt
nếu bạn điên
(fmt "#{(fmt\"#{(fmt\\\"#{user-full-name}\\\")}\")}")
;; =>
"Jordon Biondo"
Mã chỉ mở rộng cho một format
cuộc gọi để tất cả các thay thế được thực hiện theo thứ tự và được đánh giá trong thời gian chạy.
(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)))
Các cải tiến có thể được thực hiện với loại định dạng được sử dụng thay vì luôn sử dụng% s, nhưng điều đó sẽ phải được thực hiện trong thời gian chạy và sẽ thêm chi phí nhưng có thể được thực hiện bằng cách bao quanh tất cả các định dạng trong một lệnh gọi hàm định dạng độc đáo mọi thứ dựa trên về loại nhưng thực sự là kịch bản duy nhất mà bạn muốn có lẽ là nổi và bạn thậm chí có thể thực hiện (định dạng "% f" float) trong thay thế là bạn đã tuyệt vọng.
Nếu tôi làm việc với nó nhiều hơn, nhiều khả năng tôi sẽ cập nhật ý chính này thay vì câu trả lời này. https://gist.github.com/jordonbiondo/c4e22b4289be130bc59b