s.el의 s-lex-format은 실제로 원하는 것이지만 변수 이름뿐만 아니라 대체 블록 안에 코드를 실제로 넣으려면 개념 증명으로 이것을 썼습니다.
(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."
미쳤다면 fmt
다른 사람 에게 전화를 걸 수도 있습니다.fmt
(fmt "#{(fmt\"#{(fmt\\\"#{user-full-name}\\\")}\")}")
;; =>
"Jordon Biondo"
코드는 format
호출로 확장 되므로 모든 대체가 순서대로 수행되고 런타임에 평가됩니다.
(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)))
항상 % s를 사용하는 대신 사용되는 형식 유형을 개선 할 수 있지만 런타임에 수행해야하고 오버 헤드를 추가해야하지만 모든 형식 인수를 함수 형식으로 둘러 싸서 수행 할 수 있습니다. 유형에 있지만 실제로 당신이 원할 수있는 유일한 시나리오는 아마 수레이며 심지어 대체에서 (형식 "% f"float)를 수행 할 수도 있습니다.
더 많이 연구하면이 대답 대신이 요점을 업데이트 할 가능성이 큽니다. https://gist.github.com/jordonbiondo/c4e22b4289be130bc59b