Estou trabalhando para otimizar minha configuração do emacs, onde posso criar dinamicamente funções interativas para todos os temas que tenho em uma lista.
Abaixo está uma versão simplificada da construção que estou tentando fazer funcionar.
;; List containing names of functions that I want to create
(setq my/defun-list '(zz-abc
zz-def
zz-ghi))
;; Elisp macro to create an interactive defun whose name
;; is passed as the macro argument
(defmacro my/create-defun (defun-name)
`(defun ,defun-name ()
(interactive)
(let ((fn-name (symbol-name ',defun-name)))
(message "Testing creation of function %s" fn-name))))
;; Loop to call the above macro for each element in the list
;; DOES *NOT* WORK
(dolist (name my/defun-list)
(my/create-defun name))
Mas se eu desenrolar o loop manualmente, ele funcionará:
;; WORKS
(my/create-defun zz-abc)
(my/create-defun zz-def)
(my/create-defun zz-ghi)
Mas o abaixo não funciona onde passo os nomes dos símbolos (que provavelmente é o que está acontecendo quando o loop se desenrola sozinho). Observe as aspas antes dos argumentos da macro.
;; DOES *NOT* WORK
(my/create-defun 'zz-abc)
(my/create-defun 'zz-def)
(my/create-defun 'zz-ghi)
Atualizar
Graças à ajuda de @wvxvw , finalmente consegui fazer isso funcionar !
Como o @wvxvw sugere, não serei desonesto para gerar lotes para todo e qualquer caso de uso. Este foi um caso de uso especial em que, para um tema chamado XYZ
, eu quero gerar um desunião chamado load-theme/XYZ
que faz o trabalho de
- Desativando todos os outros temas que podem estar ativos
- Ligando
load-theme
paraXYZ
- Fazendo algumas coisas mais personalizadas relacionadas a esse tema; Passo as configurações personalizadas para cada tema através da lista
my/themes
.
fonte
defuns
dentro de umprogn
.progn
pode ser um formulário de nível superior (no sentido de que tudo o que se aplica aos formulários de nível superior também se aplica ao conteúdoprogn
). Mas eu questionaria a lógica de criar funções dessa maneira: por que não ter, digamos, uma tabela de has- tas com lambdas como valores?cons
es, mas pretendo convertê-los em listas com propriedades personalizadas para cada tema.(my/create-defun name)
3 vezes, então você deve definir uma função chamadaname
3 vezes.Respostas:
Aqui está uma tentativa de explicação e algumas sugestões.
Agora, vamos tentar corrigir isso:
Exemplo com a leitura de nomes de funções de uma variável
O problema era de um tipo conceitual: as macros são para gerar código quando o ambiente deseja lê-lo. Quando você executa o código você mesmo (como sendo o usuário do seu programa), já é tarde demais para fazê-lo (o ambiente deve saber até lá o que é o programa).
Uma nota marginal: eu recomendaria não juntar várias
defuns
. A razão é que isso torna a depuração muito mais complicada. A pouca redundância que você tem em definições repetidas compensa muito bem durante a fase de manutenção (e a manutenção é normalmente a fase mais longa da vida útil do programa).fonte
mapcar
listas. Isso não parece funcionar com meu caso de uso real. Eu vou cavar isso assim que puder.(mapcar (lambda (x) (message "argument: %s" x)) some-alist)
para ver qual é o argumento que você recebe e trabalhar a partir daí. Se essa é uma lista associativa, eu imagino que a saída seja algo comoargument: (foo . bar)
, então você pode acessarfoo
usandocar
ebar
usandocdr
funções.nth
fn em vez decar
ecadr
), mas osequencep
check-in estámapcar
errado. Eu estava fornecendo uma lista como entrada, mas ainda assim o mapcar não achou que fosse uma sequência. Se eu fiz(sequencep my-alist)
, isso foi nulo. Então, eu estou confuso .. Ainda tenho que depurar isso.my-alist
foinil
ou você esqueceu (ou acrescentou mais) citações, de modo que issomy-alist
era um símbolo ou foi avaliado ainda mais para ser outra coisa. Você provavelmente deseja expandir sua pergunta com o novo código para facilitar a resposta.Não exatamente desafia, mas por que não? : P
fonte
Eu tenho o seguinte no meu init:
Talvez seja um pouco mais complexo do que o necessário (especialmente essa avaliação extra), mas me permite gerar os desajustados necessários para essas propriedades (e incluir documentos com as informações corretas nas strings).
fonte