diff options
| author | Chong Yidong | 2011-02-13 15:04:33 -0500 |
|---|---|---|
| committer | Chong Yidong | 2011-02-13 15:04:33 -0500 |
| commit | d4eb88c7ab151a7cb7188c3ba03eb326ec1fa6f2 (patch) | |
| tree | f685934b7cf5ba0906ab5de0c5692185c07013b1 | |
| parent | e430810c897eb9e9594eccde36bf1f015b9ecb26 (diff) | |
| download | emacs-d4eb88c7ab151a7cb7188c3ba03eb326ec1fa6f2.tar.gz emacs-d4eb88c7ab151a7cb7188c3ba03eb326ec1fa6f2.zip | |
Bind RET in Log View mode to a command that toggles a more detailed display.
* lisp/vc/log-view.el: New command log-view-toggle-entry-display for
toggling log entries between concise and detailed forms.
(log-view-toggle-entry-display): New command.
(log-view-mode-map): Bind RET to it.
(log-view-expanded-log-entry-function): New variable.
(log-view-current-entry, log-view-inside-comment-p)
(log-view-current-tag): New functions.
(log-view-toggle-mark-entry): Use log-view-current-entry and
log-view-end-of-defun instead of searching directly with
log-view-message-re.
(log-view-end-of-defun): Likewise. Add optional ARG for
compatibility with end-of-defun.
(log-view-end-of-defun): Ignore comments and VC buttons.
* lisp/vc/vc-bzr.el (vc-bzr-expanded-log-entry): New function.
(vc-bzr-log-view-mode): Use log-view-expanded-log-entry-function.
| -rw-r--r-- | etc/NEWS | 10 | ||||
| -rw-r--r-- | lisp/ChangeLog | 19 | ||||
| -rw-r--r-- | lisp/vc/log-view.el | 195 | ||||
| -rw-r--r-- | lisp/vc/vc-bzr.el | 15 |
4 files changed, 165 insertions, 74 deletions
| @@ -608,6 +608,16 @@ the user for specifics, e.g. a merge source. | |||
| 608 | 608 | ||
| 609 | **** Currently supported by Bzr, Git, and Mercurial. | 609 | **** Currently supported by Bzr, Git, and Mercurial. |
| 610 | 610 | ||
| 611 | *** Log entries in some Log View buffers can be toggled to display a | ||
| 612 | longer description by typing RET (log-view-toggle-entry-display). | ||
| 613 | In the Log View buffers made by `C-x v L' (vc-print-root-log), you can | ||
| 614 | use this to display the full log entry for the revision at point. | ||
| 615 | |||
| 616 | **** Currently supported by Bzr. | ||
| 617 | |||
| 618 | **** Packages using Log View mode can enable this functionality by | ||
| 619 | binding `log-view-expanded-log-entry-function' to a suitable function. | ||
| 620 | |||
| 611 | ** Miscellaneous | 621 | ** Miscellaneous |
| 612 | 622 | ||
| 613 | --- | 623 | --- |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f7361b1c108..bf347d2a70f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,22 @@ | |||
| 1 | 2011-02-13 Chong Yidong <cyd@stupidchicken.com> | ||
| 2 | |||
| 3 | * vc/log-view.el: New command log-view-toggle-entry-display for | ||
| 4 | toggling log entries between concise and detailed forms. | ||
| 5 | (log-view-toggle-entry-display): New command. | ||
| 6 | (log-view-mode-map): Bind RET to it. | ||
| 7 | (log-view-expanded-log-entry-function): New variable. | ||
| 8 | (log-view-current-entry, log-view-inside-comment-p) | ||
| 9 | (log-view-current-tag): New functions. | ||
| 10 | (log-view-toggle-mark-entry): Use log-view-current-entry and | ||
| 11 | log-view-end-of-defun instead of searching directly with | ||
| 12 | log-view-message-re. | ||
| 13 | (log-view-end-of-defun): Likewise. Add optional ARG for | ||
| 14 | compatibility with end-of-defun. | ||
| 15 | (log-view-end-of-defun): Ignore comments and VC buttons. | ||
| 16 | |||
| 17 | * vc/vc-bzr.el (vc-bzr-expanded-log-entry): New function. | ||
| 18 | (vc-bzr-log-view-mode): Use log-view-expanded-log-entry-function. | ||
| 19 | |||
| 1 | 2011-02-13 Teodor Zlatanov <tzz@lifelogs.com> | 20 | 2011-02-13 Teodor Zlatanov <tzz@lifelogs.com> |
| 2 | 21 | ||
| 3 | * net/imap.el: Remove file. All the functionality is in nnimap.el. | 22 | * net/imap.el: Remove file. All the functionality is in nnimap.el. |
diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el index f71c928c693..3753904324b 100644 --- a/lisp/vc/log-view.el +++ b/lisp/vc/log-view.el | |||
| @@ -130,6 +130,7 @@ | |||
| 130 | ("z" . kill-this-buffer) | 130 | ("z" . kill-this-buffer) |
| 131 | ("q" . quit-window) | 131 | ("q" . quit-window) |
| 132 | ("g" . revert-buffer) | 132 | ("g" . revert-buffer) |
| 133 | ("\C-m" . log-view-toggle-entry-display) | ||
| 133 | 134 | ||
| 134 | ("m" . log-view-toggle-mark-entry) | 135 | ("m" . log-view-toggle-mark-entry) |
| 135 | ("e" . log-view-modify-change-comment) | 136 | ("e" . log-view-modify-change-comment) |
| @@ -180,6 +181,12 @@ | |||
| 180 | (defvar log-view-mode-hook nil | 181 | (defvar log-view-mode-hook nil |
| 181 | "Hook run at the end of `log-view-mode'.") | 182 | "Hook run at the end of `log-view-mode'.") |
| 182 | 183 | ||
| 184 | (defvar log-view-expanded-log-entry-function nil | ||
| 185 | "Function returning the detailed description of a Log View entry. | ||
| 186 | It is called by the command `log-view-toggle-entry-display' with | ||
| 187 | one arg, the revision tag (a string), and should return a string. | ||
| 188 | If it is nil, `log-view-toggle-entry-display' does nothing.") | ||
| 189 | |||
| 183 | (defface log-view-file | 190 | (defface log-view-file |
| 184 | '((((class color) (background light)) | 191 | '((((class color) (background light)) |
| 185 | (:background "grey70" :weight bold)) | 192 | (:background "grey70" :weight bold)) |
| @@ -299,15 +306,36 @@ The match group number 1 should match the revision number itself.") | |||
| 299 | (when cvsdir (setq dir (expand-file-name cvsdir dir)))) | 306 | (when cvsdir (setq dir (expand-file-name cvsdir dir)))) |
| 300 | (expand-file-name file dir)))) | 307 | (expand-file-name file dir)))) |
| 301 | 308 | ||
| 302 | (defun log-view-current-tag (&optional where) | 309 | (defun log-view-current-entry (&optional pos move) |
| 303 | (save-excursion | 310 | "Return the position and revision tag of the Log View entry at POS. |
| 304 | (when where (goto-char where)) | 311 | This is a list (BEG TAG), where BEG is a buffer position and TAG |
| 305 | (forward-line 1) | 312 | is a string. If POS is nil or omitted, it defaults to point. |
| 306 | (let ((pt (point))) | 313 | If there is no entry at POS, return nil. |
| 307 | (when (re-search-backward log-view-message-re nil t) | 314 | |
| 308 | (let ((rev (match-string-no-properties 1))) | 315 | If optional arg MOVE is non-nil, move point to BEG if found. |
| 309 | (unless (re-search-forward log-view-file-re pt t) | 316 | Otherwise, don't move point." |
| 310 | rev)))))) | 317 | (let ((looping t) |
| 318 | result) | ||
| 319 | (save-excursion | ||
| 320 | (when pos (goto-char pos)) | ||
| 321 | (forward-line 1) | ||
| 322 | (while looping | ||
| 323 | (setq pos (re-search-backward log-view-message-re nil 'move) | ||
| 324 | looping (and pos (log-view-inside-comment-p (point))))) | ||
| 325 | (when pos | ||
| 326 | (setq result | ||
| 327 | (list pos (match-string-no-properties 1))))) | ||
| 328 | (and move result (goto-char pos)) | ||
| 329 | result)) | ||
| 330 | |||
| 331 | (defun log-view-inside-comment-p (pos) | ||
| 332 | "Return non-nil if POS lies inside an expanded log entry." | ||
| 333 | (eq (get-text-property pos 'log-view-comment) t)) | ||
| 334 | |||
| 335 | (defun log-view-current-tag (&optional pos) | ||
| 336 | "Return the revision tag (a string) of the Log View entry at POS. | ||
| 337 | if POS is omitted or nil, it defaults to point." | ||
| 338 | (cadr (log-view-current-entry pos))) | ||
| 311 | 339 | ||
| 312 | (defun log-view-toggle-mark-entry () | 340 | (defun log-view-toggle-mark-entry () |
| 313 | "Toggle the marked state for the log entry at point. | 341 | "Toggle the marked state for the log entry at point. |
| @@ -317,29 +345,24 @@ entries are denoted by changing their background color. | |||
| 317 | log entries." | 345 | log entries." |
| 318 | (interactive) | 346 | (interactive) |
| 319 | (save-excursion | 347 | (save-excursion |
| 320 | (forward-line 1) | 348 | (let* ((entry (log-view-current-entry nil t)) |
| 321 | (let ((pt (point))) | 349 | (beg (car entry)) |
| 322 | (when (re-search-backward log-view-message-re nil t) | 350 | found) |
| 323 | (let ((beg (match-beginning 0)) | 351 | (when entry |
| 324 | end ov ovlist found tag) | 352 | ;; Look to see if the current entry is marked. |
| 325 | (unless (re-search-forward log-view-file-re pt t) | 353 | (setq found (get-char-property beg 'log-view-self)) |
| 326 | ;; Look to see if the current entry is marked. | 354 | (if found |
| 327 | (setq found (get-char-property (point) 'log-view-self)) | 355 | (delete-overlay found) |
| 328 | (if found | 356 | ;; Create an overlay covering this entry and change its color. |
| 329 | (delete-overlay found) | 357 | (let* ((end (if (get-text-property beg 'log-view-entry-expanded) |
| 330 | ;; Create an overlay that covers this entry and change | 358 | (next-single-property-change beg 'log-view-comment) |
| 331 | ;; its color. | 359 | (log-view-end-of-defun) |
| 332 | (setq tag (log-view-current-tag (point))) | 360 | (point))) |
| 333 | (forward-line 1) | 361 | (ov (make-overlay beg end))) |
| 334 | (setq end | 362 | (overlay-put ov 'face 'log-view-file) |
| 335 | (if (re-search-forward log-view-message-re nil t) | 363 | ;; This is used to check if the overlay is present. |
| 336 | (match-beginning 0) | 364 | (overlay-put ov 'log-view-self ov) |
| 337 | (point-max))) | 365 | (overlay-put ov 'log-view-marked (nth 1 entry)))))))) |
| 338 | (setq ov (make-overlay beg end)) | ||
| 339 | (overlay-put ov 'face 'log-view-file) | ||
| 340 | ;; This is used to check if the overlay is present. | ||
| 341 | (overlay-put ov 'log-view-self ov) | ||
| 342 | (overlay-put ov 'log-view-marked tag)))))))) | ||
| 343 | 366 | ||
| 344 | (defun log-view-get-marked () | 367 | (defun log-view-get-marked () |
| 345 | "Return the list of tags for the marked log entries." | 368 | "Return the list of tags for the marked log entries." |
| @@ -352,50 +375,74 @@ log entries." | |||
| 352 | (setq pos (overlay-end ov)))) | 375 | (setq pos (overlay-end ov)))) |
| 353 | marked-list))) | 376 | marked-list))) |
| 354 | 377 | ||
| 355 | (defun log-view-beginning-of-defun () | 378 | (defun log-view-toggle-entry-display () |
| 356 | ;; This assumes that a log entry starts with a line matching | 379 | (interactive) |
| 357 | ;; `log-view-message-re'. Modes that derive from `log-view-mode' | 380 | ;; Don't do anything unless `log-view-expanded-log-entry-function' |
| 358 | ;; for which this assumption is not valid will have to provide | 381 | ;; is defined in this mode. |
| 359 | ;; another implementation of this function. `log-view-msg-prev' | 382 | (when (functionp log-view-expanded-log-entry-function) |
| 360 | ;; does a similar job to this function, we can't use it here | 383 | (let* ((opoint (point)) |
| 361 | ;; directly because it prints messages that are not appropriate in | 384 | (entry (log-view-current-entry nil t)) |
| 362 | ;; this context and it does not move to the beginning of the buffer | 385 | (beg (car entry)) |
| 363 | ;; when the point is before the first log entry. | 386 | (buffer-read-only nil)) |
| 364 | 387 | (when entry | |
| 365 | ;; `log-view-beginning-of-defun' and `log-view-end-of-defun' have | 388 | (if (get-text-property beg 'log-view-entry-expanded) |
| 366 | ;; been checked to work with logs produced by RCS, CVS, git, | 389 | ;; If the entry is expanded, collapse it. |
| 367 | ;; mercurial and subversion. | 390 | (let ((pos (next-single-property-change beg 'log-view-comment))) |
| 368 | 391 | (unless (and pos (log-view-inside-comment-p pos)) | |
| 369 | (re-search-backward log-view-message-re nil 'move)) | 392 | (error "Broken markup in `log-view-toggle-entry-display'")) |
| 393 | (delete-region pos | ||
| 394 | (next-single-property-change pos 'log-view-comment)) | ||
| 395 | (put-text-property beg (1+ beg) 'log-view-entry-expanded nil) | ||
| 396 | (if (< opoint pos) | ||
| 397 | (goto-char opoint))) | ||
| 398 | ;; Otherwise, expand the entry. | ||
| 399 | (let ((long-entry (funcall log-view-expanded-log-entry-function | ||
| 400 | (nth 1 entry)))) | ||
| 401 | (when long-entry | ||
| 402 | (put-text-property beg (1+ beg) 'log-view-entry-expanded t) | ||
| 403 | (log-view-end-of-defun) | ||
| 404 | (setq beg (point)) | ||
| 405 | (insert long-entry "\n") | ||
| 406 | (add-text-properties | ||
| 407 | beg (point) | ||
| 408 | '(font-lock-face font-lock-comment-face log-view-comment t)) | ||
| 409 | (goto-char opoint)))))))) | ||
| 410 | |||
| 411 | (defun log-view-beginning-of-defun (&optional arg) | ||
| 412 | "Move backward to the beginning of a Log View entry. | ||
| 413 | With ARG, do it that many times. Negative ARG means move forward | ||
| 414 | to the beginning of the ARGth following entry. | ||
| 415 | |||
| 416 | This is Log View mode's default `beginning-of-defun-function'. | ||
| 417 | It assumes that a log entry starts with a line matching | ||
| 418 | `log-view-message-re'." | ||
| 419 | (if (or (null arg) (zerop arg)) | ||
| 420 | (setq arg 1)) | ||
| 421 | (if (< arg 0) | ||
| 422 | (dotimes (n (- arg)) | ||
| 423 | (log-view-end-of-defun)) | ||
| 424 | (catch 'beginning-of-buffer | ||
| 425 | (dotimes (n arg) | ||
| 426 | (or (log-view-current-entry nil t) | ||
| 427 | (throw 'beginning-of-buffer nil))) | ||
| 428 | (point)))) | ||
| 370 | 429 | ||
| 371 | (defun log-view-end-of-defun () | 430 | (defun log-view-end-of-defun () |
| 372 | ;; The idea in this function is to search for the beginning of the | 431 | "Move forward to the next Log View entry." |
| 373 | ;; next log entry using `log-view-message-re' and then go back one | 432 | (let ((looping t)) |
| 374 | ;; line when finding it. Modes that derive from `log-view-mode' for | 433 | (if (looking-at log-view-message-re) |
| 375 | ;; which this assumption is not valid will have to provide another | 434 | (goto-char (match-end 0))) |
| 376 | ;; implementation of this function. | 435 | (while looping |
| 377 | 436 | (cond | |
| 378 | ;; Look back and if there is no entry there it means we are before | 437 | ((re-search-forward log-view-message-re nil 'move) |
| 379 | ;; the first log entry, so go forward until finding one. | 438 | (unless (log-view-inside-comment-p (point)) |
| 380 | (unless (save-excursion (re-search-backward log-view-message-re nil t)) | 439 | (setq looping nil) |
| 381 | (re-search-forward log-view-message-re nil t)) | 440 | (goto-char (match-beginning 0)))) |
| 382 | 441 | ;; Don't advance past the end buttons inserted by | |
| 383 | ;; In case we are at the end of log entry going forward a line will | 442 | ;; `vc-print-log-setup-buttons'. |
| 384 | ;; make us find the next entry when searching. If we are inside of | 443 | ((looking-back "Show 2X entries Show unlimited entries") |
| 385 | ;; an entry going forward a line will still keep the point inside | 444 | (setq looping nil) |
| 386 | ;; the same entry. | 445 | (forward-line -1)))))) |
| 387 | (forward-line 1) | ||
| 388 | |||
| 389 | ;; In case we are at the beginning of an entry, move past it. | ||
| 390 | (when (looking-at log-view-message-re) | ||
| 391 | (goto-char (match-end 0)) | ||
| 392 | (forward-line 1)) | ||
| 393 | |||
| 394 | ;; Search for the start of the next log entry. Go to the end of the | ||
| 395 | ;; buffer if we could not find a next entry. | ||
| 396 | (when (re-search-forward log-view-message-re nil 'move) | ||
| 397 | (goto-char (match-beginning 0)) | ||
| 398 | (forward-line -1))) | ||
| 399 | 446 | ||
| 400 | (defvar cvs-minor-current-files) | 447 | (defvar cvs-minor-current-files) |
| 401 | (defvar cvs-branch-prefix) | 448 | (defvar cvs-branch-prefix) |
diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el index 9f86a28a575..09a622e8fed 100644 --- a/lisp/vc/vc-bzr.el +++ b/lisp/vc/vc-bzr.el | |||
| @@ -590,6 +590,7 @@ REV non-nil gets an error." | |||
| 590 | (defvar log-view-font-lock-keywords) | 590 | (defvar log-view-font-lock-keywords) |
| 591 | (defvar log-view-current-tag-function) | 591 | (defvar log-view-current-tag-function) |
| 592 | (defvar log-view-per-file-logs) | 592 | (defvar log-view-per-file-logs) |
| 593 | (defvar log-view-expanded-log-entry-function) | ||
| 593 | 594 | ||
| 594 | (define-derived-mode vc-bzr-log-view-mode log-view-mode "Bzr-Log-View" | 595 | (define-derived-mode vc-bzr-log-view-mode log-view-mode "Bzr-Log-View" |
| 595 | (remove-hook 'log-view-mode-hook 'vc-bzr-log-view-mode) ;Deactivate the hack. | 596 | (remove-hook 'log-view-mode-hook 'vc-bzr-log-view-mode) ;Deactivate the hack. |
| @@ -600,6 +601,10 @@ REV non-nil gets an error." | |||
| 600 | (if (eq vc-log-view-type 'short) | 601 | (if (eq vc-log-view-type 'short) |
| 601 | "^ *\\([0-9.]+\\): \\(.*?\\)[ \t]+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)\\( \\[merge\\]\\)?" | 602 | "^ *\\([0-9.]+\\): \\(.*?\\)[ \t]+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)\\( \\[merge\\]\\)?" |
| 602 | "^ *\\(?:revno: \\([0-9.]+\\)\\|merged: .+\\)")) | 603 | "^ *\\(?:revno: \\([0-9.]+\\)\\|merged: .+\\)")) |
| 604 | ;; Allow expanding short log entries | ||
| 605 | (when (eq vc-log-view-type 'short) | ||
| 606 | (set (make-local-variable 'log-view-expanded-log-entry-function) | ||
| 607 | 'vc-bzr-expanded-log-entry)) | ||
| 603 | (set (make-local-variable 'log-view-font-lock-keywords) | 608 | (set (make-local-variable 'log-view-font-lock-keywords) |
| 604 | ;; log-view-font-lock-keywords is careful to use the buffer-local | 609 | ;; log-view-font-lock-keywords is careful to use the buffer-local |
| 605 | ;; value of log-view-message-re only since Emacs-23. | 610 | ;; value of log-view-message-re only since Emacs-23. |
| @@ -637,6 +642,16 @@ REV non-nil gets an error." | |||
| 637 | (list vc-bzr-log-switches) | 642 | (list vc-bzr-log-switches) |
| 638 | vc-bzr-log-switches))))) | 643 | vc-bzr-log-switches))))) |
| 639 | 644 | ||
| 645 | (defun vc-bzr-expanded-log-entry (revision) | ||
| 646 | (with-temp-buffer | ||
| 647 | (apply 'vc-bzr-command "log" t nil nil | ||
| 648 | (list (format "-r%s" revision))) | ||
| 649 | (goto-char (point-min)) | ||
| 650 | (when (looking-at "^-+\n") | ||
| 651 | ;; Indent the expanded log entry. | ||
| 652 | (indent-region (match-end 0) (point-max) 2) | ||
| 653 | (buffer-substring (match-end 0) (point-max))))) | ||
| 654 | |||
| 640 | (defun vc-bzr-log-incoming (buffer remote-location) | 655 | (defun vc-bzr-log-incoming (buffer remote-location) |
| 641 | (apply 'vc-bzr-command "missing" buffer 'async nil | 656 | (apply 'vc-bzr-command "missing" buffer 'async nil |
| 642 | (list "--theirs-only" (unless (string= remote-location "") remote-location)))) | 657 | (list "--theirs-only" (unless (string= remote-location "") remote-location)))) |