Como conectar-se ao estado de buffer modificado?

8

Como na variável mode-line-modifiedinterna que exibe um asterisco na linha de modo, se o buffer for modificado.

Especificamente, quero hl-line-modedesligar quando o buffer é modificado e ativado quando não está.

Eu li a documentação sobre "Alterar ganchos", mas quero hl-line-modealternar quando desfazer uma alteração como o asterisco da linha de modo.

babá
fonte
3
Ganchos relevantes parecem ser after-change-functionse first-change-hook. Se, por algum motivo, desfazer de um buffer modificado para um não modificado não conta como uma "alteração" para esses ganchos, você pode aconselhar undoexecutar a alternância.
Dan
Consulte também a função buffer-modified-ppara testar se uma modificação ocorreu. Estou usando o after-save-hooke first-change-hookpara alternar um indicador modificado na minha barra de tabulação.
lawlist
3
se os ganchos de mudança não funcionarem perfeitamente ao desfazer, a maneira mais segura é post-command-hookverificar isso buffer-modified-p.
Malabarba

Respostas:

5

Com base nos comentários, aqui estão duas maneiras de conseguir o que você está tentando fazer. (Não testado extensivamente, portanto YMMV.)

Opção 1: post-command-hook

Crie uma função que testa se o buffer está ou não modificado e conecte-o a post-command-hook:

(defun hl-line-mode-toggle-maybe ()
  "Turn on `hl-line-mode' when buffer is unmodified, turn it off
when it is modified."
  (hl-line-mode (if (buffer-modified-p) -1 1)))

(add-hook 'post-command-hook #'hl-line-mode-toggle-maybe)

A vantagem é que é bem simples. A desvantagem é que o Emacs executará esse teste após cada comando , o que parece ser um exagero.

Opção 2: first-change-hook, after-save-hookeundo

Crie uma função para hl-line-modedesligar e conectá-la first-change-hook. Crie uma função para ativar hl-line-modee conectá-la after-save-hook. Forneça afterconselhos sobre undocomo ativar hl-line-modequando um desfazer retornou o buffer para um estado não modificado:

(defun hl-line-mode-off ()
  "Turn off `hl-line-mode'."
  (hl-line-mode -1))

(defun hl-line-mode-on ()
  "Turn off `hl-line-mode'."
  (hl-line-mode 1))

(add-hook 'first-change-hook #'hl-line-mode-off)
(add-hook 'after-save-hook   #'hl-line-mode-on)

(defadvice undo (after hl-line-when-unmodified activate)
  (unless (buffer-modified-p)
    (hl-line-mode 1)))

A vantagem é que ele chama essas funções com pouca frequência e não após cada comando. A desvantagem é que você teve que se aprofundar em conselhos, e pode haver outras maneiras imprevistas de obter um buffer para um estado não modificado que não desencadeie a etapa "ativar hl-line-modenovamente".

Dan
fonte
Ahh, sim, obrigado por colocar isso em uma resposta. Acabei usando a segunda opção para não usar a post-command-hook.
Nanny
revert-bufferparece outro caso comum que colocaria o buffer em um estado não modificado. Você pode usar o after-revert-hookpara lidar com este.
glucas
Você também precisaria de uma maneira de ativar o destaque para buffers recém-abertos - talvez o after-change-major-mode-hook?
glucas
1
Observe que add-hookpossui um localparâmetro; portanto, se você deseja apenas substituir o comportamento em determinados modos ou buffers principais, é possível.
Wilfred Hughes