[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] /srv/bzr/emacs/trunk r108043: Fixes for diff-hunk-kill.
From: |
Chong Yidong |
Subject: |
[Emacs-diffs] /srv/bzr/emacs/trunk r108043: Fixes for diff-hunk-kill. |
Date: |
Thu, 26 Apr 2012 16:00:47 +0800 |
User-agent: |
Bazaar (2.3.1) |
------------------------------------------------------------
revno: 108043
fixes bug(s): http://debbugs.gnu.org/6041 http://debbugs.gnu.org/6005
committer: Chong Yidong <address@hidden>
branch nick: trunk
timestamp: Thu 2012-04-26 16:00:47 +0800
message:
Fixes for diff-hunk-kill.
* lisp/vc/diff-mode.el (diff-beginning-of-hunk): Return a meaningful
value, for symmetry with diff-end-of-hunk.
(diff-split-hunk, diff-find-source-location)
(diff-ignore-whitespace-hunk, diff-refine-hunk): Use it.
(diff-bounds-of-hunk, diff-bounds-of-file): New functions.
(diff-restrict-view, diff-hunk-kill, diff-file-kill): Use them to
compute the relevant hunk or file properly.
(diff-file-junk-re): Add bzr's "modified file" tag.
modified:
lisp/ChangeLog
lisp/vc/diff-mode.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog 2012-04-26 03:43:32 +0000
+++ b/lisp/ChangeLog 2012-04-26 08:00:47 +0000
@@ -1,3 +1,14 @@
+2012-04-26 Chong Yidong <address@hidden>
+
+ * vc/diff-mode.el (diff-beginning-of-hunk): Return a meaningful
+ value, for symmetry with diff-end-of-hunk.
+ (diff-split-hunk, diff-find-source-location)
+ (diff-ignore-whitespace-hunk, diff-refine-hunk): Use it.
+ (diff-bounds-of-hunk, diff-bounds-of-file): New functions.
+ (diff-restrict-view, diff-hunk-kill, diff-file-kill): Use them to
+ compute the relevant hunk or file properly (Bug#6005).
+ (diff-file-junk-re): Add bzr's "modified file" tag (Bug#6041).
+
2012-04-26 Stefan Monnier <address@hidden>
* vc/vc-mtn.el:
=== modified file 'lisp/vc/diff-mode.el'
--- a/lisp/vc/diff-mode.el 2012-04-26 03:43:32 +0000
+++ b/lisp/vc/diff-mode.el 2012-04-26 08:00:47 +0000
@@ -434,6 +434,7 @@
style)
(defun diff-end-of-hunk (&optional style donttrustheader)
+ "Advance to the end of the current hunk, and return its position."
(let (end)
(when (looking-at diff-hunk-header-re)
;; Especially important for unified (because headers are ambiguous).
@@ -481,19 +482,21 @@
(goto-char (or end (point-max)))))
(defun diff-beginning-of-hunk (&optional try-harder)
- "Move back to beginning of hunk.
-If TRY-HARDER is non-nil, try to cater to the case where we're not in a hunk
-but in the file header instead, in which case move forward to the first hunk."
+ "Move back to the previous hunk beginning, and return its position.
+If point is in a file header rather than a hunk, advance to the
+next hunk if TRY-HARDER is non-nil; otherwise signal an error."
(beginning-of-line)
- (unless (looking-at diff-hunk-header-re)
+ (if (looking-at diff-hunk-header-re)
+ (point)
(forward-line 1)
(condition-case ()
(re-search-backward diff-hunk-header-re)
(error
- (if (not try-harder)
- (error "Can't find the beginning of the hunk")
- (diff-beginning-of-file-and-junk)
- (diff-hunk-next))))))
+ (unless try-harder
+ (error "Can't find the beginning of the hunk"))
+ (diff-beginning-of-file-and-junk)
+ (diff-hunk-next)
+ (point)))))
(defun diff-unified-hunk-p ()
(save-excursion
@@ -536,44 +539,72 @@
(easy-mmode-define-navigation
diff-file diff-file-header-re "file" diff-end-of-file)
+(defun diff-bounds-of-hunk ()
+ "Return the bounds of the diff hunk at point.
+The return value is a list (BEG END), which are the hunk's start
+and end positions. Signal an error if no hunk is found. If
+point is in a file header, return the bounds of the next hunk."
+ (save-excursion
+ (let ((pos (point))
+ (beg (diff-beginning-of-hunk t))
+ (end (diff-end-of-hunk)))
+ (cond ((>= end pos)
+ (list beg end))
+ ;; If this hunk ends above POS, consider the next hunk.
+ ((re-search-forward diff-hunk-header-re nil t)
+ (list (match-beginning 0) (diff-end-of-hunk)))
+ (t (error "No hunk found"))))))
+
+(defun diff-bounds-of-file ()
+ "Return the bounds of the file segment at point.
+The return value is a list (BEG END), which are the segment's
+start and end positions."
+ (save-excursion
+ (let ((pos (point))
+ (beg (progn (diff-beginning-of-file-and-junk)
+ (point))))
+ (diff-end-of-file)
+ ;; bzr puts a newline after the last hunk.
+ (while (looking-at "^\n")
+ (forward-char 1))
+ (if (> pos (point))
+ (error "Not inside a file diff"))
+ (list beg (point)))))
+
(defun diff-restrict-view (&optional arg)
"Restrict the view to the current hunk.
If the prefix ARG is given, restrict the view to the current file instead."
(interactive "P")
- (save-excursion
- (if arg (diff-beginning-of-file) (diff-beginning-of-hunk 'try-harder))
- (narrow-to-region (point)
- (progn (if arg (diff-end-of-file) (diff-end-of-hunk))
- (point)))
- (set (make-local-variable 'diff-narrowed-to) (if arg 'file 'hunk))))
-
+ (apply 'narrow-to-region
+ (if arg (diff-bounds-of-file) (diff-bounds-of-hunk)))
+ (set (make-local-variable 'diff-narrowed-to) (if arg 'file 'hunk)))
(defun diff-hunk-kill ()
- "Kill current hunk."
+ "Kill the hunk at point."
(interactive)
- (diff-beginning-of-hunk)
- (let* ((start (point))
- ;; Search the second match, since we're looking at the first.
- (nexthunk (when (re-search-forward diff-hunk-header-re nil t 2)
- (match-beginning 0)))
- (firsthunk (ignore-errors
- (goto-char start)
- (diff-beginning-of-file) (diff-hunk-next) (point)))
- (nextfile (ignore-errors (diff-file-next) (point)))
+ (let* ((hunk-bounds (diff-bounds-of-hunk))
+ (file-bounds (ignore-errors (diff-bounds-of-file)))
+ ;; If the current hunk is the only one for its file, kill the
+ ;; file header too.
+ (bounds (if (and file-bounds
+ (progn (goto-char (car file-bounds))
+ (= (progn (diff-hunk-next) (point))
+ (car hunk-bounds)))
+ (progn (goto-char (cadr hunk-bounds))
+ ;; bzr puts a newline after the last hunk.
+ (while (looking-at "^\n")
+ (forward-char 1))
+ (= (point) (cadr file-bounds))))
+ file-bounds
+ hunk-bounds))
(inhibit-read-only t))
- (goto-char start)
- (if (and firsthunk (= firsthunk start)
- (or (null nexthunk)
- (and nextfile (> nexthunk nextfile))))
- ;; It's the only hunk for this file, so kill the file.
- (diff-file-kill)
- (diff-end-of-hunk)
- (kill-region start (point)))))
+ (apply 'kill-region bounds)
+ (goto-char (car bounds))))
;; "index ", "old mode", "new mode", "new file mode" and
;; "deleted file mode" are output by git-diff.
(defconst diff-file-junk-re
- "diff \\|index \\|\\(?:deleted file\\|new\\(?: file\\)?\\|old\\) mode")
+ "diff \\|index \\|\\(?:deleted file\\|new\\(?: file\\)?\\|old\\) mode\\|===
modified file")
(defun diff-beginning-of-file-and-junk ()
"Go to the beginning of file-related diff-info.
@@ -625,13 +656,8 @@
(defun diff-file-kill ()
"Kill current file's hunks."
(interactive)
- (let ((orig (point))
- (start (progn (diff-beginning-of-file-and-junk) (point)))
- (inhibit-read-only t))
- (diff-end-of-file)
- (if (looking-at "^\n") (forward-char 1)) ;`tla' generates such diffs.
- (if (> orig (point)) (error "Not inside a file diff"))
- (kill-region start (point))))
+ (let ((inhibit-read-only t))
+ (apply 'kill-region (diff-bounds-of-file))))
(defun diff-kill-junk ()
"Kill spurious empty diffs."
@@ -667,7 +693,7 @@
(interactive)
(beginning-of-line)
(let ((pos (point))
- (start (progn (diff-beginning-of-hunk) (point))))
+ (start (diff-beginning-of-hunk)))
(unless (looking-at diff-hunk-header-re-unified)
(error "diff-split-hunk only works on unified context diffs"))
(forward-line 1)
@@ -1589,8 +1615,7 @@
NOPROMPT, if non-nil, means not to prompt the user."
(save-excursion
(let* ((other (diff-xor other-file diff-jump-to-old-file))
- (char-offset (- (point) (progn (diff-beginning-of-hunk 'try-harder)
- (point))))
+ (char-offset (- (point) (diff-beginning-of-hunk t)))
;; Check that the hunk is well-formed. Otherwise diff-mode and
;; the user may disagree on what constitutes the hunk
;; (e.g. because an empty line truncates the hunk mid-course),
@@ -1777,8 +1802,7 @@
(defun diff-ignore-whitespace-hunk ()
"Re-diff the current hunk, ignoring whitespace differences."
(interactive)
- (let* ((char-offset (- (point) (progn (diff-beginning-of-hunk 'try-harder)
- (point))))
+ (let* ((char-offset (- (point) (diff-beginning-of-hunk t)))
(opts (case (char-after) (?@ "-bu") (?* "-bc") (t "-b")))
(line-nb (and (or (looking-at "[^0-9]+\\([0-9]+\\)")
(error "Can't find line number"))
@@ -1854,7 +1878,7 @@
(interactive)
(require 'smerge-mode)
(save-excursion
- (diff-beginning-of-hunk 'try-harder)
+ (diff-beginning-of-hunk t)
(let* ((start (point))
(style (diff-hunk-style)) ;Skips the hunk header as well.
(beg (point))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r108043: Fixes for diff-hunk-kill.,
Chong Yidong <=