Emacs: обновлять аннотации git-gutter при промежуточных или неустановленных изменениях в буфере magit-status.

Я использую git-gutter для визуализации изменений, которые я вношу в файлы с контролем версий, и magit для подготовки /committing/diffing и т. д.

При работе над проектом я обычно всегда держу окно magit-status открытым. Моя проблема заключается в том, что когда я помещаю или удаляю изменения в буфере magit-status, а затем переключаюсь обратно в окно, показывающее файл, статус которого я только что обновил, краевые аннотации, созданные git-gutter не настраивается автоматически. (Мой текущий обходной путь для запуска обновления — нажать SPC Backspace, а затем C-x C-s, чтобы сохранить файл, но это не очень эффективно.)

Я посмотрел на git-gutter.el, и, конечно же, он предоставляет настраиваемую переменную с именем git-gutter:update-hooks, для которой установлено значение

(after-save-hook after-revert-hook window-configuration-change-hook)

по умолчанию. Так что все, что мне действительно нужно сделать, это добавить правильный хук в этот список, и я буду готов к работе. Как называется хук, который запускается при переключении окон? Я просмотрел различные разделы руководства по Elisp и не смог найти то, что ищу. В качестве альтернативы, предоставляет ли magit хук, который запускается при промежуточном или неустановленном изменении?


ИЗМЕНИТЬ:

Если вы читаете это, потому что столкнулись с похожей проблемой: оба ответа, которые я получил ниже, являются рабочими решениями! Для более новых версий magit решение @lunaryorn короткое и приятное. решение @Jordon Biondo требует добавления немного большего количества пользовательского кода, но содержит общие (!) советы по созданию пользовательских хуков и внедрению их в существующую функциональность. Итак, поскольку я могу принять только один ответ: Повысьте свою SO-карму, вознаградив обоих авторов голосованием :)


person itsjeyd    schedule 28.04.2014    source источник
comment
Я бегло взглянул на исходный код Magit и не увидел никаких хуков в конце промежуточных функций, в конце функций процесса вызова или в функциях буфера обновления. Таким образом, одной из возможностей было бы создать свою собственную функцию для элемента magit-stage-item и поместить функцию обновления git-gutter в конец ее. Хотя это может быть излишним, post-command-hook запускается каждый раз, когда вы моргаете или чихаете (что, я думаю, включает и моргание).   -  person lawlist    schedule 28.04.2014
comment
@lawlist Magit запускает magit-revert-buffer-hook в любом буфере репо после каждой операции.   -  person lunaryorn    schedule 29.04.2014
comment
@lunaryorn - спасибо - в моей установке Magit нет этой зацепки, поэтому я посмотрю самую последнюю версию и посмотрю, что она может предложить.   -  person lawlist    schedule 29.04.2014


Ответы (3)


Изменить: с последними версиями magit и git-gutter это больше не требует такой сложной настройки, см. ответ лунариорнс для получения более актуального и простого решения.


Исходный ответ:

Метод переключения окна может быть немного излишним, поскольку вы будете обновлять больше, чем нужно.

Magit не предлагает хуки до/после этапа/вне сцены, однако мы можем сделать свои собственные хуки, воспользовавшись советом!

Вы можете определить две переменные для хуков stage и unstage.

(defvar my-magit-after-stage-hooks nil
  "Hooks to be run after staging one item in magit.")

(defvar my-magit-after-unstage-hooks nil
  "Hooks to be run after unstaging one item in magit.")

Есть хорошая функция-оболочка для запуска хуков: run-hooks< /a> мы будем использовать совет функции для запуска наших пользовательских хуков после magit-stage-item и magit-unstage-item

(defadvice magit-stage-item (after run-my-after-stage-hooks activate)
  "Run `my-magit-after-stage-hooks` after staging an item in magit."
  (when (called-interactively-p 'interactive)
    (run-hooks 'my-magit-after-stage-hooks)))

(defadvice magit-unstage-item (after run-my-after-unstage-hooks activate)
  "Run `my-magit-after-unstage-hooks` after unstaging an item in magit."
  (when (called-interactively-p 'interactive)
    (run-hooks 'my-magit-after-unstage-hooks)))

Для нашего хука мы можем просто перебрать все буферы и обновить git-gutter, когда это применимо, потому что мы не знаем, что является подготовленным, а что нет. Поэтому мы просто обновим отображение git-gutter для всех видимых буферов, работающих в режиме git-gutter. (Если вы хотите использовать все буферы git-gutter, просто удалите вызов get-buffer-window.)

(defun my-refresh-visible-git-gutter-buffers ()
  "Refresh git-gutter-mode on all visible git-gutter-mode buffers."
  (dolist (buff (buffer-list))
    (with-current-buffer buff
      (when (and git-gutter-mode (get-buffer-window buff))
        (git-gutter-mode t)))))

Наконец, просто добавьте функцию хука в свой собственный хук!

(add-hook 'my-magit-after-unstage-hooks
          'my-refresh-visible-git-gutter-buffers)
(add-hook 'my-magit-after-stage-hooks
          'my-refresh-visible-git-gutter-buffers)

В идеале мы бы знали, какие файлы были поставлены/не помещены в сцену, и обновляли бы только эти буферы, если бы вы могли воспользоваться советом вокруг более глубокой функции magit и получить имя элемента буфера состояния magit, с которым вы работаете, и обновить только это. Но это хорошее начало!

автоматическое обновление git gitter

person Jordon Biondo    schedule 28.04.2014
comment
Это замечательно! Большое спасибо, что нашли время, чтобы так подробно ответить на мой вопрос. Я оценил код, который вы разместили в моем буфере *scratch*, и, похоже, он делает именно то, что я хочу. Хотел бы я голосовать больше одного раза ;) А если серьезно, я многому научился из этого, так что еще раз спасибо! - person itsjeyd; 29.04.2014

Вот что мне нужно было сделать с текущим magit:

(add-hook 'magit-post-refresh-hook
          #'git-gutter:update-all-windows)
person Mattias Bengtsson    schedule 01.07.2016
comment
Команда git-gutter:update-all-windows не имеет для меня никакого эффекта, если я не запускаю ее непосредственно в одном из буферов с желобом Git. Это может быть связано с недавним изменением в git-gutter, так как я думал, что ваше исправление работает для меня в сентябре?! - person ntc2; 06.12.2016
comment
Это все еще работает нормально для меня со всеми пакетами, обновленными всего несколько минут назад. Я работаю с global-git-gutter-mode FWIW. - person Mattias Bengtsson; 05.01.2017
comment
А еще у меня есть (add-hook 'magit-status-mode-hook #'magit-filenotify-mode), не уверен, что это имеет значение. - person Mattias Bengtsson; 05.01.2017
comment
Я не пробовал добавлять magit-filenotify-mode к magit-status-mode-hook, но это зависит от другого пакета: github.com/magit/ magit-filenotify. - person ntc2; 14.01.2017

Обратите внимание, что текущая версия magit не использует `magit-revert-buffer-hook'. Таким образом, решение лунариорна может не сработать.

Вы можете добавить функцию перехватчиков обновлений git-gutter magit-after-revert-hook и magit-not-reverted-hook, которые вызываются, когда magit обновляет все посещенные буферы из текущего репозитория (например, после фиксации или команды «g»):

(add-hook 'git-gutter:update-hooks 'magit-after-revert-hook)
(add-hook 'git-gutter:update-hooks 'magit-not-reverted-hook)
person 4DA    schedule 30.08.2015