diff options
Diffstat (limited to 'lisp/vc/diff-mode.el')
| -rw-r--r-- | lisp/vc/diff-mode.el | 85 |
1 files changed, 36 insertions, 49 deletions
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 66043059d14..0a618dc8f39 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el | |||
| @@ -53,9 +53,10 @@ | |||
| 53 | ;; - Handle `diff -b' output in context->unified. | 53 | ;; - Handle `diff -b' output in context->unified. |
| 54 | 54 | ||
| 55 | ;;; Code: | 55 | ;;; Code: |
| 56 | (require 'easy-mmode) | ||
| 57 | (require 'track-changes) | ||
| 56 | (eval-when-compile (require 'cl-lib)) | 58 | (eval-when-compile (require 'cl-lib)) |
| 57 | (eval-when-compile (require 'subr-x)) | 59 | (eval-when-compile (require 'subr-x)) |
| 58 | (require 'easy-mmode) | ||
| 59 | 60 | ||
| 60 | (autoload 'vc-find-revision "vc") | 61 | (autoload 'vc-find-revision "vc") |
| 61 | (autoload 'vc-find-revision-no-save "vc") | 62 | (autoload 'vc-find-revision-no-save "vc") |
| @@ -1431,38 +1432,23 @@ else cover the whole buffer." | |||
| 1431 | (if (buffer-modified-p) (diff-fixup-modifs (point-min) (point-max))) | 1432 | (if (buffer-modified-p) (diff-fixup-modifs (point-min) (point-max))) |
| 1432 | nil) | 1433 | nil) |
| 1433 | 1434 | ||
| 1434 | ;; It turns out that making changes in the buffer from within an | 1435 | (defvar-local diff--track-changes nil) |
| 1435 | ;; *-change-function is asking for trouble, whereas making them | 1436 | |
| 1436 | ;; from a post-command-hook doesn't pose much problems | 1437 | (defun diff--track-changes-signal (tracker) |
| 1437 | (defvar diff-unhandled-changes nil) | 1438 | (cl-assert (eq tracker diff--track-changes)) |
| 1438 | (defun diff-after-change-function (beg end _len) | 1439 | (track-changes-fetch tracker #'diff--track-changes-function)) |
| 1439 | "Remember to fixup the hunk header. | 1440 | |
| 1440 | See `after-change-functions' for the meaning of BEG, END and LEN." | 1441 | (defun diff--track-changes-function (beg end _before) |
| 1441 | ;; Ignoring changes when inhibit-read-only is set is strictly speaking | 1442 | (with-demoted-errors "%S" |
| 1442 | ;; incorrect, but it turns out that inhibit-read-only is normally not set | 1443 | (save-excursion |
| 1443 | ;; inside editing commands, while it tends to be set when the buffer gets | 1444 | (goto-char beg) |
| 1444 | ;; updated by an async process or by a conversion function, both of which | 1445 | ;; Maybe we've cut the end of the hunk before point. |
| 1445 | ;; would rather not be uselessly slowed down by this hook. | 1446 | (if (and (bolp) (not (bobp))) (backward-char 1)) |
| 1446 | (when (and (not undo-in-progress) (not inhibit-read-only)) | 1447 | ;; We used to fixup modifs on all the changes, but it turns out that |
| 1447 | (if diff-unhandled-changes | 1448 | ;; it's safer not to do it on big changes, e.g. when yanking a big |
| 1448 | (setq diff-unhandled-changes | 1449 | ;; diff, or when the user edits the header, since we might then |
| 1449 | (cons (min beg (car diff-unhandled-changes)) | 1450 | ;; screw up perfectly correct values. --Stef |
| 1450 | (max end (cdr diff-unhandled-changes)))) | 1451 | (when (ignore-errors (diff-beginning-of-hunk t)) |
| 1451 | (setq diff-unhandled-changes (cons beg end))))) | ||
| 1452 | |||
| 1453 | (defun diff-post-command-hook () | ||
| 1454 | "Fixup hunk headers if necessary." | ||
| 1455 | (when (consp diff-unhandled-changes) | ||
| 1456 | (ignore-errors | ||
| 1457 | (save-excursion | ||
| 1458 | (goto-char (car diff-unhandled-changes)) | ||
| 1459 | ;; Maybe we've cut the end of the hunk before point. | ||
| 1460 | (if (and (bolp) (not (bobp))) (backward-char 1)) | ||
| 1461 | ;; We used to fixup modifs on all the changes, but it turns out that | ||
| 1462 | ;; it's safer not to do it on big changes, e.g. when yanking a big | ||
| 1463 | ;; diff, or when the user edits the header, since we might then | ||
| 1464 | ;; screw up perfectly correct values. --Stef | ||
| 1465 | (diff-beginning-of-hunk t) | ||
| 1466 | (let* ((style (if (looking-at "\\*\\*\\*") 'context)) | 1452 | (let* ((style (if (looking-at "\\*\\*\\*") 'context)) |
| 1467 | (start (line-beginning-position (if (eq style 'context) 3 2))) | 1453 | (start (line-beginning-position (if (eq style 'context) 3 2))) |
| 1468 | (mid (if (eq style 'context) | 1454 | (mid (if (eq style 'context) |
| @@ -1470,17 +1456,16 @@ See `after-change-functions' for the meaning of BEG, END and LEN." | |||
| 1470 | (re-search-forward diff-context-mid-hunk-header-re | 1456 | (re-search-forward diff-context-mid-hunk-header-re |
| 1471 | nil t))))) | 1457 | nil t))))) |
| 1472 | (when (and ;; Don't try to fixup changes in the hunk header. | 1458 | (when (and ;; Don't try to fixup changes in the hunk header. |
| 1473 | (>= (car diff-unhandled-changes) start) | 1459 | (>= beg start) |
| 1474 | ;; Don't try to fixup changes in the mid-hunk header either. | 1460 | ;; Don't try to fixup changes in the mid-hunk header either. |
| 1475 | (or (not mid) | 1461 | (or (not mid) |
| 1476 | (< (cdr diff-unhandled-changes) (match-beginning 0)) | 1462 | (< end (match-beginning 0)) |
| 1477 | (> (car diff-unhandled-changes) (match-end 0))) | 1463 | (> beg (match-end 0))) |
| 1478 | (save-excursion | 1464 | (save-excursion |
| 1479 | (diff-end-of-hunk nil 'donttrustheader) | 1465 | (diff-end-of-hunk nil 'donttrustheader) |
| 1480 | ;; Don't try to fixup changes past the end of the hunk. | 1466 | ;; Don't try to fixup changes past the end of the hunk. |
| 1481 | (>= (point) (cdr diff-unhandled-changes)))) | 1467 | (>= (point) end))) |
| 1482 | (diff-fixup-modifs (point) (cdr diff-unhandled-changes))))) | 1468 | (diff-fixup-modifs (point) end))))))) |
| 1483 | (setq diff-unhandled-changes nil)))) | ||
| 1484 | 1469 | ||
| 1485 | (defun diff-next-error (arg reset) | 1470 | (defun diff-next-error (arg reset) |
| 1486 | ;; Select a window that displays the current buffer so that point | 1471 | ;; Select a window that displays the current buffer so that point |
| @@ -1560,9 +1545,8 @@ a diff with \\[diff-reverse-direction]. | |||
| 1560 | ;; setup change hooks | 1545 | ;; setup change hooks |
| 1561 | (if (not diff-update-on-the-fly) | 1546 | (if (not diff-update-on-the-fly) |
| 1562 | (add-hook 'write-contents-functions #'diff-write-contents-hooks nil t) | 1547 | (add-hook 'write-contents-functions #'diff-write-contents-hooks nil t) |
| 1563 | (make-local-variable 'diff-unhandled-changes) | 1548 | (setq diff--track-changes |
| 1564 | (add-hook 'after-change-functions #'diff-after-change-function nil t) | 1549 | (track-changes-register #'diff--track-changes-signal :nobefore t))) |
| 1565 | (add-hook 'post-command-hook #'diff-post-command-hook nil t)) | ||
| 1566 | 1550 | ||
| 1567 | ;; add-log support | 1551 | ;; add-log support |
| 1568 | (setq-local add-log-current-defun-function #'diff-current-defun) | 1552 | (setq-local add-log-current-defun-function #'diff-current-defun) |
| @@ -1581,12 +1565,15 @@ a diff with \\[diff-reverse-direction]. | |||
| 1581 | \\{diff-minor-mode-map}" | 1565 | \\{diff-minor-mode-map}" |
| 1582 | :group 'diff-mode :lighter " Diff" | 1566 | :group 'diff-mode :lighter " Diff" |
| 1583 | ;; FIXME: setup font-lock | 1567 | ;; FIXME: setup font-lock |
| 1584 | ;; setup change hooks | 1568 | (when diff--track-changes (track-changes-unregister diff--track-changes)) |
| 1585 | (if (not diff-update-on-the-fly) | 1569 | (remove-hook 'write-contents-functions #'diff-write-contents-hooks t) |
| 1586 | (add-hook 'write-contents-functions #'diff-write-contents-hooks nil t) | 1570 | (when diff-minor-mode |
| 1587 | (make-local-variable 'diff-unhandled-changes) | 1571 | (if (not diff-update-on-the-fly) |
| 1588 | (add-hook 'after-change-functions #'diff-after-change-function nil t) | 1572 | (add-hook 'write-contents-functions #'diff-write-contents-hooks nil t) |
| 1589 | (add-hook 'post-command-hook #'diff-post-command-hook nil t))) | 1573 | (unless diff--track-changes |
| 1574 | (setq diff--track-changes | ||
| 1575 | (track-changes-register #'diff--track-changes-signal | ||
| 1576 | :nobefore t)))))) | ||
| 1590 | 1577 | ||
| 1591 | ;;; Handy hook functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 1578 | ;;; Handy hook functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 1592 | 1579 | ||