Elisp é uma linguagem interpretada. Você pode colocar o código específico da versão no seu .emacs
, mas proteja-o testando no tempo de carregamento que está operando na versão correta.
(if (is-new-feature-available)
(shiny-new-feature)
(old-less-nifty-feature))
Este código funcionará em todas as versões porque (shiny-new-feature)
é avaliado apenas quando (is-new-feature-available)
retorna true. Grande parte dessa resposta é dedicada a como implementar (is-new-feature-available)
.
Lidando com diferentes conjuntos de recursos
É melhor testar se um recurso está disponível do que testar a versão do Emacs. Às vezes, o recurso pode estar disponível como um pacote opcional. Se você deseja executar o código no XEmacs ou em outra variante do Emacs, ele pode ter adquirido os mesmos recursos em versões diferentes. Use a função boundp
para testar se uma variável está disponível e fboundp
para testar se uma função está disponível.
Por exemplo, o seguinte trecho vincula uma chave para alternar, visual-line-mode
se disponível, e longlines-mode
caso contrário.
(global-set-key "\eml" (if (fboundp 'visual-line-mode)
'visual-line-mode
'longlines-mode))
Às vezes, em vez de testar o recurso, é mais fácil executar um pequeno pedaço de código e ignorar qualquer erro devido a funções indefinidas, argumentos inválidos etc. Não faça isso para grandes quantidades de código, pois isso tornará seu código muito difícil de depurar.
Por exemplo, não quero ver uma barra de ferramentas. As versões mais antigas do Emacs não as possuíam. O GNU Emacs e o XEmacs adicionaram esse recurso de maneiras diferentes e o tornaram o padrão. Aqui está como eu desligá-los. A set-specifier
função é específica para o XEmacs e default-toolbar-visible-p
específica para versões recentes o suficiente do Emacs; usando condition-case
cuida de ambos os requisitos. O GNU Emacs fornece uma função dedicada, então apenas testo se essa função está disponível.
;; For XEmacs
(condition-case nil
(set-specifier default-toolbar-visible-p nil)
(error nil))
;; For GNU Emacs
(if (fboundp 'tool-bar-mode)
(tool-bar-mode 0))
Alguns nomes de rosto mudam ao longo das versões. Use facep
para testar a disponibilidade de um nome de rosto.
(let ((face (if (facep 'mode-line) 'mode-line 'modeline)))
(set-face-background face …))
Às vezes, você pode querer carregar um pacote legal, se presente, e não fazer nada se o pacote não estiver disponível. require
tem um argumento opcional para isso.
(require 'tex-site nil t) ;; Load AUCTeX if available
Esse argumento foi introduzido no GNU Emacs 20.4 e não está disponível no XEmacs; portanto, se você quiser ir tão longe, precisará envolvê-lo condition-case
ou usá-lo load
(o que não verifica as bibliotecas já carregadas) .
Limite as dependências da versão aos recursos no nível do usuário. Não use recursos de programação mais recentes que não estejam disponíveis em todas as versões que você deseja oferecer suporte: você precisará fornecer uma versão de compatibilidade para versões mais antigas, e é mais fácil manter uma única versão.
Às vezes, você precisa de um recurso em muitos lugares e está disponível em todas as implementações de que você gosta, mas de uma maneira diferente. Esse é o caso principalmente se você deseja suportar o XEmacs e o GNU Emacs: eles tinham uma tendência frustrante de copiar os recursos um do outro, mas não a interface. Nesse caso, definir uma função de compatibilidade é mais conveniente do que testar no ponto de uso.
Por exemplo, o código a seguir define uma função que retorna o sistema de janelas do quadro atual, a maneira moderna GNU, a maneira moderna do XEmacs e a maneira antiga quando você não podia combinar quadros de terminal e GUI na mesma instância.
(defalias 'compat-window-system
(cond
((fboundp 'window-system) #'window-system)
((fboundp 'device-type)
(lambda (&optional frame)
(device-type (frame-device frame))))
(t
(lambda (&optional frame) window-system))))
Dependências do ambiente
Não há muito código que precise depender da plataforma. A variável system-type
indica o sistema operacional. Eu o uso exclusivamente para ativar alguns hacks para ms-dos
(sim, meus arquivos são antigos) e windows-nt
.
Você pode adicionar diretórios ao seu caminho de pesquisa executável ( PATH
), mas geralmente é melhor fazê-lo fora do Emacs, no seu .profile
sistema para Unix e no painel de controle do Windows. Para testar se um programa externo está disponível, ligue executable-find
.
Para código que precisa agir de maneira diferente, dependendo do tipo de GUI, se houver, verifique window-type
ou seus sucessores (veja acima).
Arquivos de inicialização
Para máxima compatibilidade, insira seu código ~/.emacs
. O GNU Emacs começou a procurar na ~/emacs.d
versão 22. O XEmacs começou a procurar ~/.xemacs
na versão 21.4. Uma abordagem alternativa é ~/.emacs
inserir e concluir o código de compatibilidade carregando o arquivo principal. Coloque um (setq load-home-init-file t)
lugar para evitar que as versões recentes do XEmacs perguntem se você deseja movê-lo .emacs
para o local exclusivo do XEmacs.
Versões diferentes do Emacs podem ter expansão diferente e incompatível para algumas macros. Portanto, não compartilhe seus arquivos compilados em bytes entre versões, compile os arquivos em cada máquina.
Às vezes, um recurso está obsoleto, mas você ainda deseja usá-lo, porque é tudo o que existe em outra versão que você deseja oferecer suporte. Os avisos do compilador de bytes vêm da byte-obsolete-variable
propriedade
(cond
((not (boundp 'desktop-enable))
(defvaralias 'desktop-enable 'desktop-save-mode))
((get 'desktop-enable 'byte-obsolete-variable)
(put 'desktop-enable 'byte-obsolete-variable nil)))
¹ Relativamente falando, comparado com os XEmacs mais antigos.
window-system
etc. - podem ser respondidas com razoabilidade aqui.