Idealmente, eu gostaria de poder armazenar todo o conteúdo do meu .emacs.d
diretório e fazê-lo "simplesmente funcionar" em qualquer Emacs em que o carregue, mas ainda assim tirar proveito de todos os recursos do ambiente específico, como os sistemas de janelas da GUI.
Não estou procurando uma enciclopédia de recursos incompatíveis. Eu gostaria de saber como verificar os recursos, SO, versão, gráficos, etc., e como tirar proveito deles sem quebrar o código para outras configurações.
Que técnicas básicas posso usar para escrever o Elisp que funciona em várias versões do Emacs comuns em estado selvagem (por exemplo, 22.x +) e em várias plataformas subjacentes (por exemplo, OSX, Linux, Windows e outro * nix), enquanto aproveita a plataforma e recursos específicos da versão, onde aplicável?
fonte
window-system
etc. - podem ser respondidas com razoabilidade aqui.forward-char
e você quer que a pergunta seja alteradascroll-up
? Se o OP deseja compatibilidade com o Emacs 22+, deixe-o em paz. E não, a questão colocada não é apenas sobre o OS X. E sim, ainda existem muitas pessoas usando versões mais antigas do Emacs (algumas até com mais de 22 anos, FWIW).Respostas:
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.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 efboundp
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, elonglines-mode
caso contrário.À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 edefault-toolbar-visible-p
específica para versões recentes o suficiente do Emacs; usandocondition-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.Alguns nomes de rosto mudam ao longo das versões. Use
facep
para testar a disponibilidade de um nome de rosto.À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.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á-loload
(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.
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 params-dos
(sim, meus arquivos são antigos) ewindows-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, ligueexecutable-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¹ Relativamente falando, comparado com os XEmacs mais antigos.
fonte
(Wiki da comunidade. Adicione o seu!)
Se houver uma função, adicionada em uma versão mais recente do Emacs, que você gostaria de usar, verifique se está definida com
fboundp
e defina uma função de compatibilidade se não estiver definida.É uma má idéia atribuir à função de compatibilidade o mesmo nome que a função real, pois outro código Elisp pode estar usando o mesmo
fboundp
truque. Portanto, use um prefixo para a função de compatibilidade e usedefalias
o mesmo nome, se estiver definido. Por exemplo:Se alguma parte da configuração se aplicar apenas a um determinado sistema operacional, existem algumas possibilidades diferentes. Você pode verificar o
system-type
variável, que retornagnu/linux
,darwin
,windows-nt
e alguns outros (veja a docstring).Você pode ser tentado a usar
window-system
, apesar de sua doutrina declarar que "O uso dessa variável como booleano está obsoleto" e recomenda o usodisplay-graphic-p
. Observe que o Emacs pode usar diferentes tipos de telas para quadros diferentes atualmente (por exemplo, um quadro em um terminal e outro em uma janela "adequada"), portanto, isso pode causar surpresas. Usecurrent-frame-configuration
ouget-buffer-window-list
em seu elisp para fazer a escolha certa.Convém verificar se você está executando o sabor certo do emacs. Use featurep para verificar a variante. Por exemplo:
Você também pode usá-lo para verificar se módulos específicos estão carregados. Por exemplo, se você usar apenas um pequeno e fácil de definir defun do common-lisp, poderá optar por definir em vez de exigir. Por exemplo:
Evite armazenar arquivos .elc. Eles não são compatíveis com versões anteriores ou anteriores com algumas versões do Emacs.
fonte
Se você estiver usando funções,
cl-lib
mas não quiser usar as versões descontinuadas sem espaço para nome, torne a biblioteca de compatibilidade cl-lib uma dependência do seu projeto. Isso permitirá que você use ascl-
funções com espaço para nome , mas mantenha a compatibilidade com versões anteriores.fonte
cl-lib
assim mesmo? Que vantagem tem sobre issocl
, que existe desde pelo menos 20 anos atrás?cl
está obsoleto e provavelmente será removido eventualmente. O uso no código causou avisos de compilador de bytes por um longo tempo. Eu acho que o motivo é que eles querem reutilizar alguns doscl
nomes (comodolist
) com diferentes semânticas.