как правильно захватить вывод `diff` в буфере (без первого открытия файла)?

резюме

Если вы выберете diff вывод в файл name = *. Diff и откроете этот файл в буфере, вы получите красиво отформатированный режим = Diff , Как получить это напрямую, без предварительного захвата файла?

Детали

Я часто использую diff не только через ediff-buffers (который мне нравится), но и для более неясных целей, таких как diff процессы. Я также использую Emacs в течение нескольких десятилетий, но продолжаю изучать новые аспекты и использовать. Поэтому я не был так удивлен, как было любопытно найти это, когда я это сделал (из каталога dir/локального репозитория git )

$ git diff master origin/master > /tmp/foo__local_vs_remote.diff

и открыл файл в буфере, он отобразился в красиво/полезно раскрашенном (à la ediff ) mode = Diff. Я никогда раньше не был

  1. captured diff output to a file
  2. named the file *.diff
  3. opened the file in Emacs

Но теперь я пытаюсь захватить вывод diff непосредственно в буфер и , чтобы получить вывод, подобный результату счастливого режима = Diff, и я терпеть неудачу.

универсальность поиска

Note also that, since I use diff in lots of contexts, I'm looking for a solution to the general problem, and not, e.g., just to the git diff problem (which I suspect Magit etc have solved). универсальность поиска, I'll test 3 usecases: "normal" file-vs-file diff, git diff, and process-substitution diff.

Платформа

$ lsb_release -ds
LMDE 2 Betsy
$ cat /etc/debian_version
8.3
$ uname -rv
3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u4 (2016-02-29)
$ emacs --version
GNU Emacs 24.4.1

опции

оболочка-команда

Если я сделаю следующее (возможно, после перехода в буфер с соответствующим рабочим каталогом)

  1. M-!
  2. C-x b *Shell Command Output* (where the output of M-!==M-x оболочка-команда goes by default)
  3. M-x diff-mode

... Я получаю хорошо отформатированный вывод. более того

  • это работает для всех 3 тестовых корпусов
  • если выполняется M -! с помощью другой команды diff , новый вывод просто перезаписывает старый, но буфер поддерживает diff-mode без вмешательства пользователя
  • изменения привязки клавиш (как в режиме Термин режим)

Выбранный ответ.

Оболочка режима

Если я либо

  1. M-x shell, goto the correct dir/folder, and run git diff master origin/master
  2. am in a buffer on the correct dir/folder, and run M-& git diff master origin/master

Я получаю страшный WARNING: терминал не работает полностью .

Термин режим

Как Пользователь Emacs указывает , Mx term работает лучше для этой usecase, чем Mx shell : если I Mx term , перейдите в правильную папку dir/и запустите git diff master origin/master , я получаю красиво раскрашенный вывод. Это не совсем режим = Diff, но он выполняет эту работу. К сожалению

  • That only works for git diff: I get no colorization for either process-substitution or file diff.
  • I find the Термин режим keybinding changes highly annoying.
  • I also found Термин режим navigation odd: when editing history, my cursor would sometimes bounce around oddly. solved).
2

2 ответы

Вы всегда можете написать функцию, чтобы выполнить все повторяющиеся шаги для вас. Это должно помочь вам начать:

(defun diff-generic(command)
  (interactive "sDiff command:")
  (let ((buffer (generate-new-buffer "*diff-generic*")))
    (with-current-buffer buffer (diff-mode))
    (call-process-shell-command command nil buffer 0)
    (switch-to-buffer buffer)))

In general you can do M-x diff to get that diff output for two arbitrary files. More info on that here: (info "(emacs) Diff Mode")

Magit действительно предоставляет функциональность diff, но учтите, что он использует собственный режим, называемый magit-diff-mode , который отличается от общего emacs diff-mode .

Also emacs bundled package VC provides diff functionality for version control diffs. Unlike magit it works with backends other than git and uses diff-mode, also you can use ediff. Relevant manual: (info "(emacs) Old Revisions")

3
добавлено
Я обновил свой ответ, это должно быть то, что вы хотите.
добавлено автор John Fiala, источник
см. раздел = «поиск общей». Как это будет обрабатывать, например, замену процесса?
добавлено автор kraymer, источник

Пытаться

  1. M-!
  2. C-x b *Shell Command Output* (where the output of M-!==M-x shell-command goes by default)
  3. M-x diff-mode
2
добавлено
Те, кто читает этот ответ, должны знать, что терминал WARNING: не работает полностью не разрешен этим принятым решением. Он может работать для этого случая с ограниченным доступом, но если один из ищет универсальность в соответствии с запросом OP, используйте M-x term в качестве полного решения. См. Документацию Emacs по причинам.
добавлено автор Emacs User, источник
см. причины выбора в вопросе section = shell-command
добавлено автор kraymer, источник