Как определить несколько граней emacs?
-
20-12-2019 - |
Вопрос
Я пытаюсь определить некоторые грани шрифта emacs, чтобы выполнить некоторую пользовательскую подсветку.Кажется, это работает, когда я определяю их по отдельности:
(defface my-r-face `((t (:foreground "red"))) "Red highlight")
(defvar m-r-face 'my-r-face "Red.")
(defface my-g-face `((t (:foreground "green"))) "Green highlight")
(defvar m-g-face 'my-g-face "Green.")
(defface my-b-face `((t (:foreground "#0088ff"))) "Blue highlight")
(defvar m-b-face 'my-b-face "Blue.")
....etc
Однако у меня их несколько десятков, и я хочу определить их все за один раз из какой-нибудь цветовой таблицы:
(setq ctable '(("red" "r")
("orange" "o")
("yellow" "y")
("#88ff00" "gy")
("green" "g")
("#00ff88" "gc")
("cyan" "c")
("#0088ff" "bc")
("blue" "b")
("purple" "bm")
("magenta" "m")
("#ff0088" "rm")
("grey" "lg")
("white" "w") ))
Моя трудность заключается в сборке названий символов для каждой грани, т.е. объединении "my-" и "-face" по обе стороны записи из таблицы.Я обнаружил (стажер), что могу создать новый символ из строки, однако этот символ тогда неприемлем для (defface), поскольку кажется, что то, что я делаю, эквивалентно (defface 'my-r-face ..., и defface не нравится символ в кавычках и ожидает (обезображивай мое-р-лицо ..вместо.Моя попытка заключается в следующем:
(dolist (tpl ctable)
(defvar (intern (concat "my-" (nth 1 tpl) "-face"))
(quote (intern (concat "my-" (nth 1 tpl) "-face"))) "colour")
(defface (intern (concat "my-" (nth 1 tpl) "-face"))
`((t (:foreground ,(car tpl)))) "Highlight" :group 'fortran)
)
Выполнение этого приводит к
Lisp error: (wrong-type-argument symbolp (intern (concat "fegs-" (nth 1 tpl) "-face")))
(defvar (intern (concat "fegs-" ... "-face")) (quote (intern ...)) "colour")
Кто-нибудь может пролить некоторый свет на то, что я делаю неправильно, или если я лаю совсем не на то дерево, и есть лучший способ сделать это?
Спасибо.
Решение
Defvar - это особая форма, Defface - это макрос (поэтому аргументы передаются неравной).Вы пытались использовать что-то в строке
(eval `(defface ,(intern "foo") '((t (:foreground "red"))) "Highlight" :group 'fortran))
(eval `(defvar ,(intern "bar")))
. Другие советы
Вы можете избежать eval
:
(defconst my-ctable '(...))
(defmacro my-init-cfaces ()
`(progn
,@(mapcar (lambda (tpl)
`(defface ,(intern (format "my-%s-face" (nth 1 tpl)))
'((t :foreground ,(car tpl)))
,(format "Face for color %s." (car tpl))
:group 'fortran))
my-ctable)))
(my-init-cfaces)
полный код, который работал в конце, выглядит следующим образом:
(setq ctable '(("red" "r")
("orange" "o")
("yellow" "y")
("#88ff00" "gy")
("green" "g")
("#00ff88" "gc")
("cyan" "c")
("#0088ff" "bc")
("blue" "b")
("purple" "bm")
("magenta" "m")
("#ff0088" "rm")
("grey" "lg")
("white" "w") ))
(dolist (tpl ctable)
(let ((fname (concat "fegs-" (nth 1 tpl) "-face")))
(eval `(defface ,(intern fname) '((t (:foreground ,(car tpl)))) "Highlight" :group 'fortran))
(eval `(defvar ,(intern fname) ',(intern fname)))
)
)
.
Моя линия Defvar немного отличается, поскольку это позволяет поднять лицо подсветкой в другом месте в качестве глобальной переменной.