font-lock-add-keywords não está funcionando

Aug 18 2020

Tenho tentado adicionar realce de sintaxe personalizado para dígitos usando font-lock-add-keywordse regex.

Tenho procurado todos os recursos do Emacs para fazer isso e, embora tenha sido capaz de definir um rosto com sucesso, font-lock-add-keywordsnão está funcionando por nenhuma razão aparente.

Até copiei os exemplos de diferentes fontes e tentei fazê-los funcionar diretamente, sem nenhum sucesso aparente. Não consigo descobrir o que há de errado com meu código. Não estou recebendo nenhum erro, mas quando tento avaliar o font-lock-add-keywords(com C-x C-e), ele imprime nilno *Messages*buffer.

Atualizar

Segui o conselho de Gilles e criei um modo menor, configurei font-lock-add-keywordspara esse modo menor personalizado e usei uma citação para o rosto. Embora eu possa ver o modo secundário na linha de modo e saber que está funcionando, font-lock-add-keywordsainda não parece funcionar. Aqui está meu código atualizado:

(defgroup gio-group nil
  "Group for customization"
  :prefix "gio-")

(defface gio-highlight-numbers-face
  '((t :inherit (default)
       :foreground "#ffff00"))
  "Face for numbers"
  :group 'gio-group )

(define-minor-mode gio-minor-mode
  "Minor mode for customizaion"
  :init-value t
  :lighter " GioMode"
  :global t
  :group 'gio-group)

(font-lock-add-keywords 'gio-minor-mode '(("[0-9]+" . 'gio-highlight-numbers-face)))

Estou executando o GNU Emacs 26.3 (build 1, x86_64-w64-mingw32) no Windows 10. Qualquer ajuda é muito apreciada! Obrigado!

Respostas

2 Gyo Aug 19 2020 at 17:00

Com mais pesquisas e alguma ajuda dos comentários de Gilles e Lindydancer, descobri que não é possível adicionar palavras-chave do Font Lock a modos menores. Em vez disso, você deve adicionar e remover as palavras-chave para o modo principal quando o modo secundário é carregado e descarregado.

Aqui está o código de trabalho que destaca as palavras-chave usando um modo secundário:

(defgroup gio-group nil
  "Group for customization"
  :prefix "gio-")

(defface gio-highlight-numbers-face
  '((t :inherit (default)
       :foreground "#ffff00"))
  "Face for numbers"
  :group 'gio-group )

(defvar gio-keywords '(("\\(\\b\\|[-]\\)\\([-]?\\([0-9]+\\)\\(\\.?[0-9]\\)*\\)\\b" . 'gio-highlight-numbers-face)) ;; Integers & Decimals
  "Keywords for gio-minor-mode highlighting")

(define-minor-mode gio-minor-mode
  "Minor mode for customization"
  :init-value 1
  :lighter " GioMode"
  :group 'gio-group
  (when (bound-and-true-p gio-minor-mode)
    (font-lock-add-keywords nil gio-keywords)
    (font-lock-fontify-buffer))
  (when (not (bound-and-true-p gio-minor-mode))
    (font-lock-remove-keywords nil gio-keywords)
    (font-lock-fontify-buffer)))

(define-globalized-minor-mode gio-global-minor-mode gio-minor-mode gio-minor-mode :group 'gio-group)
(gio-global-minor-mode 1)
Gilles'SO-stopbeingevil' Aug 19 2020 at 05:18

font-lock-add-keywordsadiciona palavras-chave para um modo principal específico , como modo Lisp ou modo C ou modo HTML. Uma vez que font-lock-modenão é um modo principal, (font-lock-add-keywords 'font-lock-mode …)nunca tem qualquer efeito.

Se você realmente deseja palavras-chave de bloqueio de fonte que se apliquem a todos os modos principais, é necessário definir um modo secundário. É assim que o modo Espaço em branco funciona. Muitos modos de espaço em branco são mais complicados do que o necessário. Talvez você possa adicionar uma configuração de “destaque de dígito” ao modo de espaço em branco, mas pode ser mais fácil definir seu próprio modo. A função de conveniência define-minor-modeajuda, mas você ainda precisa adicionar e remover as palavras-chave manualmente quando o modo estiver ativado ou desativado, chamando (font-lock-add-keywords nil …)e (font-lock-remove-keywords nil …). Consulte Posso adicionar destaque em um modo menor? para obter instruções.

Além disso, há um problema em como os rostos funcionam: o nome de um rosto é um símbolo que não é uma variável. A (MATCHER . FACESPEC)forma de font-lock-keywordsrequer FACESPECser uma expressão cujo valor especifica um rosto. custom-faces-highlight-numbers-facenão funciona porque não é uma expressão válida, pois o símbolo custom-faces-highlight-numbers-facenão está vinculado. Existem duas soluções para isso. A solução tradicional é definir uma variável com o mesmo nome da face; é assim que funciona para os rostos que o modo Font Lock define, mas

Observe que, no novo código, na grande maioria dos casos, não há necessidade de criar variáveis ​​que especifiquem nomes de rosto. Basta usar rostos diretamente. O bloqueio de fonte não é um modelo a ser seguido nesta área.

A solução recomendada, mas complicada, é citar o símbolo.

(font-lock-add-keywords 'gyo-highlight-numbers-mode '(("[0-9]+" . 'custom-faces-highlight-numbers-face)))