Fontify uma região de um buffer com outro modo principal

12

Eu tenho um buffer que mostra a documentação para os módulos Ansible. Este buffer possui seu próprio modo principal, que fornece todo o material padrão. Notavelmente, ele tipifica o buffer para destacar a marcação embutida, opções, seções, etc. Em suma, é bem parecido com M-x man.

Na parte inferior da documentação, geralmente existem alguns exemplos de código no YAML. Eu gostaria de tipificar isso também. Eu poderia adicionar minhas próprias palavras-chave de bloqueio de fonte para YAML, é claro, mas prefiro reutilizar a fonte do modo YAML.

Como eu posso fazer isso? Especificamente, como posso usar um modo principal diferente para tipificar uma região específica de um buffer?

Observe que o modo YAML não precisa estar ativo nessa região. O buffer inteiro é apenas um buffer de exibição passivo e não pretende ser editado. Eu realmente só preciso da fonte produzida como se o Modo YAML estivesse ativo nessa região.

Presumo que poderia copiar a região do buffer para um buffer temporário, habilitar o Modo YAML, tipificar o buffer e copiar todas as propriedades de texto. Isso funcionaria? Em caso afirmativo, como copio propriedades de texto e quais são as propriedades relevantes para copiar? Ou existe uma abordagem melhor?

lunaryorn
fonte
Como a fonte não-yaml é implementada? Você aplica propriedades de texto manualmente ou usa o modo de bloqueio de fonte?
Malabarba
Os links neste post resumem pelo menos uma boa parte das opções disponíveis: wisdomandwonder.com/link/8610/…
grettke

Respostas:

10

Recentemente, me deparei com um problema semelhante, basicamente queria fonte de trechos de código na documentação que obtive em outra fonte. Eu segui a abordagem mencionada no final da sua resposta e funcionou bem para mim. A função que eu acabei com algo como o seguinte

(defun my-fontify-yaml (text)
  (with-temp-buffer
    (erase-buffer)
    (insert text)
    (delay-mode-hooks (yaml-mode))
    (font-lock-default-function 'yaml-mode)
    (font-lock-default-fontify-region (point-min)
                                      (point-max)
                                      nil)
    (buffer-string)))

Como o @Malabarba apontou nos comentários, a abordagem simples acima não funcionará se o buffer de destino usar o modo de bloqueio de fonte. No entanto, podemos induzir o modo de bloqueio de fonte a acreditar que a sequência já está bloqueada, definindo a propriedade text font-lock-facecomo face, (obtemos a facepropriedade definida quando usamos a função acima) e definindo a propriedade text fontifiedcomo t. A função a seguir pega uma string retornada pela função acima e faz o processamento necessário para que a string seja inserida em fonte (isso é obtido da org-src-font-lock-fontify-blockfunção do modo organizacional

(defun my-fontify-using-faces (text)
  (let ((pos 0))
    (while (setq next (next-single-property-change pos 'face text))
      (put-text-property pos next 'font-lock-face (get-text-property pos 'face text) text)
      (setq pos next))
    (add-text-properties 0  (length text) '(fontified t) text)
    text))

Agora você pode usá-lo da seguinte maneira

(insert (my-fontify-using-faces (my-fontify-yaml "application: test\nversion: 1")))
Iqbal Ansari
fonte
Essa é a mesma solução que encontrei sx.el, mas é importante observar que só funcionará se o buffer de destino não usar o modo de bloqueio de fonte.
Malabarba
Certo! Eu só percebi isso funcionou para mim, porque eu usei no buffer onde font-lock não foi utilizado (tampão de Ajuda)
Iqbal Ansari
O @Malabarba encontrou uma maneira de fazer isso funcionar com buffers de destino com o modo de bloqueio de fonte ativado
Iqbal Ansari
Muito obrigado, funciona perfeitamente !
lunaryorn
Ah legal! Ainda bem que pude ajudar :)
Iqbal Ansari
3

A biblioteca Narrow Indirect ( narrow-indirect) pode ajudar aqui - dê uma olhada no comentário do cabeçalho. Baseia-se em:

  1. estreitamento, que limita a edição a uma parte de um buffer e
  2. buffers indiretos, que copiam um buffer em outro para o qual você pode alterar o modo principal.

Observe que a restrição é desativada por padrão porque é considerada não amigável para iniciantes (a ligação padrão é C-x n n). Você pode habilitá-lo colocando o seguinte no seu arquivo init:

(put 'narrow-to-region 'disabled nil)

Você também pode olhar para o meu artesanal myfn-narrow-indirectno meu conf .

freakhill
fonte
O estreitamento realmente afeta o bloqueio da fonte, ou seja, mantém-o longe da região reduzida? O bloqueio de fonte nunca remove restrições de buffer?
lunaryorn
De qualquer forma, um pacote wiki não é uma opção.
lunaryorn
Além disso, você não precisa remover a disabledpropriedade de um comando para chamá-lo do Emacs Lisp. Afeta apenas o uso interativo.
lunaryorn
0

Eu sugeriria olhar para org-src-font-lock-fontify-block, que fornece essa funcionalidade para os blocos de origem do modo organizacional. Parece apenas copiar as partes relevantes para outro buffer, ativar o modo principal e, em seguida, copiar o texto com fonte novamente. Hackish, mas parece funcionar.

Joakim Hårsman
fonte
2
Essa resposta parece mais um comentário, na medida em que fornece uma orientação sugerida para lidar com o problema, mas não uma resposta completa. Por favor, considere alterá-lo para um comentário.
Dan