* [patch] add interactive browse of revisions from vc *Annotate* buffers @ 2004-01-12 2:54 Benjamin Rutt 2004-01-12 5:30 ` Andre Spiegel 2004-01-12 11:06 ` Kim F. Storm 0 siblings, 2 replies; 43+ messages in thread From: Benjamin Rutt @ 2004-01-12 2:54 UTC (permalink / raw) I wrote this patch because I wanted to be able to browse forward and backwards to prev and next revisions from vc.el *Annotate* buffers. That way, I can see which member of my work group is responsible for entering a particular line of a CVS-controlled file (it's sometimes not enough to just vc-annotate a buffer, since sometimes users reformat or reindent lines of source code that they didn't originally write). This patch allows you, from a vc-annotate-mode buffer, to press C-c C-p to go to the previous revision and C-c C-n to go to the next revision. It's currently only implemented for CVS, since vc-annotate is only implemented for CVS anyway. The way I incremented (or decremented) a revision number for CVS was to add (or subtract) one to the last number in the dotted revision number. So, it works for the CVS head files with revisions like "1.23" or for branches with revisions like "1.2.1.3". If this patch is accepted, I'll write a patch for info so this gets into the docs as well. I have signed papers for emacs, FYI. The patch below patches both vc.el and vc-cvs.el, as I had to define a backend function and route it through vc-cvs.el, since I didn't want anything cvs-specific creeping into vc.el, even though no vc-annotate functionality exists for any other backends at the moment. Thanks, and let me know of any comments or feedback you may have. Benjamin Rutt --- vc.el.orig 2004-01-10 21:51:37.000000000 -0500 +++ vc.el 2004-01-11 21:53:20.000000000 -0500 @@ -628,6 +628,8 @@ (defvar vc-annotate-mode-map (let ((m (make-sparse-keymap))) (define-key m [menu-bar] (make-sparse-keymap "VC-Annotate")) + (define-key m "\C-c\C-p" 'vc-annotate-prev-version) + (define-key m "\C-c\C-n" 'vc-annotate-next-version) m) "Local keymap used for VC-Annotate mode.") @@ -2778,6 +2780,10 @@ (defvar vc-annotate-ratio nil "Global variable.") (defvar vc-annotate-backend nil "Global variable.") +(defvar vc-annotate-derived-from-info nil + "Internal variable tracking buffer-local info about the file + which caused the *Annotate* buffer to be formed .") + (defconst vc-annotate-font-lock-keywords ;; The fontification is done by vc-annotate-lines instead of font-lock. '((vc-annotate-lines))) @@ -2885,7 +2891,12 @@ (unless (eq vc-annotate-display-mode 'fullscale) (vc-annotate-display-select nil 'fullscale)) :style toggle :selected - (eq vc-annotate-display-mode 'fullscale)]))) + (eq vc-annotate-display-mode 'fullscale)]) + (list "--") + (list ["Annotate previous revision" + (vc-annotate-prev-version)]) + (list ["Annotate next revision" + (vc-annotate-next-version)]))) ;; Define the menu (if (or (featurep 'easymenu) (load "easymenu" t)) (easy-menu-define vc-annotate-mode-menu vc-annotate-mode-map @@ -2922,7 +2933,7 @@ ;;;; the contents in BUFFER. ;;;###autoload -(defun vc-annotate (prefix) +(defun vc-annotate (prefix &optional revision display-mode) "Display the edit history of the current file using colours. This command creates a buffer that shows, for each line of the current @@ -2949,19 +2960,24 @@ colors. `vc-annotate-background' specifies the background color." (interactive "P") (vc-ensure-vc-buffer) - (let* ((temp-buffer-name (concat "*Annotate " (buffer-name) "*")) + (let* ((temp-buffer-name nil) (temp-buffer-show-function 'vc-annotate-display-select) - (rev (vc-workfile-version buffer-file-name)) + (rev (or revision (vc-workfile-version buffer-file-name))) + (bfn buffer-file-name) (vc-annotate-version - (if prefix (read-string - (format "Annotate from version: (default %s) " rev) - nil nil rev) - rev))) - (if prefix - (setq vc-annotate-display-mode - (float (string-to-number - (read-string "Annotate span days: (default 20) " - nil nil "20"))))) + (if prefix (read-string + (format "Annotate from version: (default %s) " rev) + nil nil rev) + rev))) + (if display-mode + (setq vc-annotate-display-mode display-mode) + (if prefix + (setq vc-annotate-display-mode + (float (string-to-number + (read-string "Annotate span days: (default 20) " + nil nil "20")))))) + (setq temp-buffer-name (format "*Annotate %s (rev %s)*" + (buffer-name) vc-annotate-version)) (setq vc-annotate-backend (vc-backend buffer-file-name)) (message "Annotating...") (if (not (vc-find-backend-function vc-annotate-backend 'annotate-command)) @@ -2972,6 +2988,11 @@ buffer-file-name (get-buffer temp-buffer-name) vc-annotate-version)) + (save-excursion + (set-buffer temp-buffer-name) + (set (make-local-variable 'vc-annotate-derived-from-info) + (list vc-annotate-version bfn vc-annotate-display-mode))) + ;; Don't use the temp-buffer-name until the buffer is created ;; (only after `with-output-to-temp-buffer'.) (setq vc-annotate-buffers @@ -2979,6 +3000,70 @@ (list (cons (get-buffer temp-buffer-name) vc-annotate-backend)))) (message "Annotating... done"))) +(defun vc-annotate-prev-version () + (interactive) + (vc-annotate-warp-version t)) + +(defun vc-annotate-next-version () + (interactive) + (vc-annotate-warp-version nil)) + +;; return the new revision as a string, or else return nil if it +;; cannot be decremented any further. This method is invoked from a +;; buffer visiting the `filename' argument. +(defun vc-annotate-decrement-revision (filename rev) + (setq vc-annotate-backend (vc-backend buffer-file-name)) + (vc-call-backend vc-annotate-backend 'decrement-revision filename rev)) + +;; return the new revision as a string, or else return nil if it +;; cannot be incremented any further. This method is invoked from a +;; buffer visiting the `filename' argument. +(defun vc-annotate-increment-revision (filename rev) + (setq vc-annotate-backend (vc-backend buffer-file-name)) + (vc-call-backend vc-annotate-backend 'increment-revision filename rev)) + +(defun vc-current-line () + "Returns the current buffer's line number." + (let ((oldpoint (point)) start) + (save-excursion + (save-restriction + (goto-char (point-min)) + (widen) + (forward-line 0) + (setq start (point)) + (goto-char oldpoint) + (forward-line 0) + (1+ (count-lines (point-min) (point))))))) + +(defun vc-annotate-warp-version (backwards) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer!") + (let* ((oldline (vc-current-line)) + (derived-from-rev (car vc-annotate-derived-from-info)) + (derived-from-filename (cadr vc-annotate-derived-from-info)) + (derived-from-display-mode (caddr vc-annotate-derived-from-info)) + (newrev nil)) + + (save-window-excursion + (find-file derived-from-filename) + (setq newrev + (if backwards + (vc-annotate-decrement-revision derived-from-filename + derived-from-rev) + (vc-annotate-increment-revision derived-from-filename + derived-from-rev)))) + (if (not newrev) + (message "Cannot locate any revision %s %s" + (if backwards "before" "after") derived-from-rev) + (save-window-excursion + (find-file derived-from-filename) + (vc-annotate nil newrev derived-from-display-mode)) + (kill-buffer (current-buffer)) ;; kill the buffer we started from + (switch-to-buffer (car (car (last vc-annotate-buffers)))) + (goto-line (min oldline (progn (goto-char (point-max)) + (previous-line) + (vc-current-line)))))))) + (defun vc-annotate-car-last-cons (a-list) "Return car of last cons in association list A-LIST." (if (not (eq nil (cdr a-list))) --- vc-cvs.el.orig 2004-01-11 21:31:30.000000000 -0500 +++ vc-cvs.el 2004-01-11 21:30:28.000000000 -0500 @@ -625,6 +625,24 @@ (beginning-of-line nil) (vc-cvs-annotate-time)))))) +(defun vc-cvs-decrement-revision (filename rev) + (let ((ls (split-string rev "\\."))) + (setq ls (nreverse ls)) + (if (string= (car ls) "1") + nil ;; return nil if the revision cannot be decremented any further + (setq ls (cons (int-to-string (1- (string-to-int (car ls)))) (cdr ls))) + (setq ls (nreverse ls)) + (mapconcat 'identity ls ".")))) + +(defun vc-cvs-increment-revision (filename rev) + (if (string= rev (vc-workfile-version filename)) + nil ;; return nil if the revision cannot be incremented any further + (let ((ls (split-string rev "\\."))) + (setq ls (nreverse ls)) + (setq ls (cons (int-to-string (1+ (string-to-int (car ls)))) (cdr ls))) + (setq ls (nreverse ls)) + (mapconcat 'identity ls ".")))) + ;;; ;;; Snapshot system ;;; ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 2:54 [patch] add interactive browse of revisions from vc *Annotate* buffers Benjamin Rutt @ 2004-01-12 5:30 ` Andre Spiegel 2004-01-12 11:06 ` Kim F. Storm 1 sibling, 0 replies; 43+ messages in thread From: Andre Spiegel @ 2004-01-12 5:30 UTC (permalink / raw) Cc: emacs-devel On Mon, 2004-01-12 at 03:54, Benjamin Rutt wrote: > I wrote this patch because I wanted to be able to browse forward and > backwards to prev and next revisions from vc.el *Annotate* buffers. > That way, I can see which member of my work group is responsible for > entering a particular line of a CVS-controlled file (it's sometimes > not enough to just vc-annotate a buffer, since sometimes users > reformat or reindent lines of source code that they didn't originally > write). This looks excellent and it should definitely be included. (I've been wishing for something like this myself.) I will check out the code and your legal assignments and get back to you about it. Thanks for that contribution. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 2:54 [patch] add interactive browse of revisions from vc *Annotate* buffers Benjamin Rutt 2004-01-12 5:30 ` Andre Spiegel @ 2004-01-12 11:06 ` Kim F. Storm 2004-01-12 13:58 ` Benjamin Rutt 1 sibling, 1 reply; 43+ messages in thread From: Kim F. Storm @ 2004-01-12 11:06 UTC (permalink / raw) Cc: emacs-devel Benjamin Rutt <brutt+news@bloomington.in.us> writes: > I wrote this patch because I wanted to be able to browse forward and > backwards to prev and next revisions from vc.el *Annotate* buffers. > That way, I can see which member of my work group is responsible for > entering a particular line of a CVS-controlled file (it's sometimes > not enough to just vc-annotate a buffer, since sometimes users > reformat or reindent lines of source code that they didn't originally > write). This patch allows you, from a vc-annotate-mode buffer, to > press C-c C-p to go to the previous revision and C-c C-n to go to the > next revision. It's currently only implemented for CVS, since > vc-annotate is only implemented for CVS anyway. That is a very good feature indeed. Thanks! However, I would like an extension to this feature so that C-u C-c C-p would pick up the revision from the current line of the annotate buffer and annotate the previous revision to that revision, rather than the revision of the work file as such. This would make it easier to backtrack a specific change in case there are many (unrelated) revision in the file. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 11:06 ` Kim F. Storm @ 2004-01-12 13:58 ` Benjamin Rutt 2004-01-12 17:11 ` Kim F. Storm 0 siblings, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-12 13:58 UTC (permalink / raw) Cc: emacs-devel storm@cua.dk (Kim F. Storm) writes: > Benjamin Rutt <brutt+news@bloomington.in.us> writes: > >> I wrote this patch because I wanted to be able to browse forward and >> backwards to prev and next revisions from vc.el *Annotate* buffers. >> That way, I can see which member of my work group is responsible for >> entering a particular line of a CVS-controlled file (it's sometimes >> not enough to just vc-annotate a buffer, since sometimes users >> reformat or reindent lines of source code that they didn't originally >> write). This patch allows you, from a vc-annotate-mode buffer, to >> press C-c C-p to go to the previous revision and C-c C-n to go to the >> next revision. It's currently only implemented for CVS, since >> vc-annotate is only implemented for CVS anyway. > > That is a very good feature indeed. Thanks! > > However, I would like an extension to this feature so that > C-u C-c C-p > would pick up the revision from the current line of the annotate > buffer and annotate the previous revision to that revision, rather > than the revision of the work file as such. > > This would make it easier to backtrack a specific change in case there > are many (unrelated) revision in the file. I'd like to implement your idea, however I want to make sure I understand it completely. Here's an example. Let's say you have file foo.c, at revision 1.24, and here's the result from C-x v g when visiting foo.c: Annotations for foo.c *************** 1.1 (rutt 07-Apr-03): int main () 1.3 (rutt 07-Apr-03): { 1.24 (rutt 07-Apr-03): return 0; 1.1 (rutt 07-Apr-03): } and let's say the cursor is on the line where revision 1.3 is at. Are you saying you'd like a function to warp you instantly back to 1.3, instead of having to go back iteratively through 1.23, 1.22, 1.21, ..., 1.4, 1.3? If this isn't your idea, could you give an example of what your idea is? Thanks, -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 13:58 ` Benjamin Rutt @ 2004-01-12 17:11 ` Kim F. Storm 2004-01-12 17:20 ` Benjamin Rutt 0 siblings, 1 reply; 43+ messages in thread From: Kim F. Storm @ 2004-01-12 17:11 UTC (permalink / raw) Cc: emacs-devel Benjamin Rutt <brutt+news@bloomington.in.us> writes: > and let's say the cursor is on the line where revision 1.3 is at. Are > you saying you'd like a function to warp you instantly back to 1.3, > instead of having to go back iteratively through 1.23, 1.22, 1.21, > ..., 1.4, 1.3? If this isn't your idea, could you give an example of > what your idea is? Thanks, Actually, I was thinking about going back to 1.2 -- i.e. to see when the _previous_ change to that line happened (unless it's new in 1.3 of course). -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 17:11 ` Kim F. Storm @ 2004-01-12 17:20 ` Benjamin Rutt 2004-01-12 20:09 ` Andre Spiegel 0 siblings, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-12 17:20 UTC (permalink / raw) Cc: emacs-devel storm@cua.dk (Kim F. Storm) writes: > Benjamin Rutt <brutt+news@bloomington.in.us> writes: > >> and let's say the cursor is on the line where revision 1.3 is at. Are >> you saying you'd like a function to warp you instantly back to 1.3, >> instead of having to go back iteratively through 1.23, 1.22, 1.21, >> ..., 1.4, 1.3? If this isn't your idea, could you give an example of >> what your idea is? Thanks, > > Actually, I was thinking about going back to 1.2 -- i.e. to see when > the _previous_ change to that line happened (unless it's new in 1.3 > of course). I think that's certainly possible. What I'm thinking now is the following: if there's a prefix argument to the function vc-annotate-prev-version, alter behavior in the following manner: 1) if the prefix argument is numeric, go backwards that many versions if possible 2) otherwise, go to the revision prior to the revision of the current line (what Kim Storm was asking for). The "revision of the current line" extractor will have to be made generic through a backend, since there's no guarantee that the *Annotate* buffer will have the version number at the beginning of the line followed by whitespace, although that's true for CVS at the moment. As far as your comment "(unless it's new in 1.3 of course)" above, I think I'll just leave it up to the user recognize when that happens, and trust them to go forwards in time one revision at that time. I also think I'd like to add a keybinding such that pressing RET in any of the *Annotate* buffer lines which contain a revision number simply does "annotate the revision mentioned on this line". -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 17:20 ` Benjamin Rutt @ 2004-01-12 20:09 ` Andre Spiegel 2004-01-12 20:35 ` Benjamin Rutt 0 siblings, 1 reply; 43+ messages in thread From: Andre Spiegel @ 2004-01-12 20:09 UTC (permalink / raw) Cc: emacs-devel I like the features you (Benjamin) are suggesting but the keybindings seem a bit problematic to me. Since those features would be very important in VC Annotate, I wonder if you couldn't use simpler bindings. Ideally, I'd put the annotate buffer in view mode and use "p" and "n" for previous and next, but these are already bound to View-search-last-regexp-backward/forward. Do people think it's justified to replace that binding in vc-annotate-mode? I would think the relative importance justifies it. To annotate from the revision _before_ the one on the current line (which I feel is the most important of those new features), "f" could be used (similar to Dired), without any clash in view mode. I know this has the potential to become an endless discussion, but perhaps we can just go through one iteration and then decide :-) ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 20:09 ` Andre Spiegel @ 2004-01-12 20:35 ` Benjamin Rutt 2004-01-13 10:57 ` Kim F. Storm 0 siblings, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-12 20:35 UTC (permalink / raw) Cc: emacs-devel Andre Spiegel <spiegel@gnu.org> writes: > I like the features you (Benjamin) are suggesting but the keybindings > seem a bit problematic to me. Since those features would be very > important in VC Annotate, I wonder if you couldn't use simpler > bindings. Ideally, I'd put the annotate buffer in view mode and use "p" > and "n" for previous and next, but these are already bound to > View-search-last-regexp-backward/forward. Do people think it's > justified to replace that binding in vc-annotate-mode? I would think > the relative importance justifies it. To annotate from the revision > _before_ the one on the current line (which I feel is the most important > of those new features), "f" could be used (similar to Dired), without > any clash in view mode. I'm not a view-mode user, so I can't give my opinion on how I'd feel about those bindings being clobbered, but I do agree that simpler key bindings will be better. Also, if we don't do something like derive annotate-mode from view-mode, we should at least make the annotate buffer read-only once it is built. I like the idea of moving the "annotate the revision _before_ the one on the current line" command away from being just invokable via a prefix modifier of another command, to being a first-class citizen in itself, invokable directly. I don't care what actual keys are used myself, I'll let some others give their opinions on that. I wouldn't have a problem with using "p", "n" and "f" as you've described above. -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-12 20:35 ` Benjamin Rutt @ 2004-01-13 10:57 ` Kim F. Storm 2004-01-14 15:45 ` Richard Stallman 0 siblings, 1 reply; 43+ messages in thread From: Kim F. Storm @ 2004-01-13 10:57 UTC (permalink / raw) Cc: Andre Spiegel, emacs-devel Benjamin Rutt <brutt+news@bloomington.in.us> writes: > I like the idea of moving the "annotate the revision _before_ the one > on the current line" command away from being just invokable via a > prefix modifier of another command, to being a first-class citizen in > itself, invokable directly. I suggest using `a' as a mnemonic for this (annontate this line) > > I don't care what actual keys are used myself, I'll let some others > give their opinions on that. I wouldn't have a problem with using > "p", "n" and "f" as you've described above. Since annotating is a somewhat time consuming activity, I don't mind (actually I prefer) having to type two keys to "annotate another version." So I suggest using M-n, M-p, and M-a. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-13 10:57 ` Kim F. Storm @ 2004-01-14 15:45 ` Richard Stallman 2004-01-14 21:55 ` Kim F. Storm 0 siblings, 1 reply; 43+ messages in thread From: Richard Stallman @ 2004-01-14 15:45 UTC (permalink / raw) Cc: brutt+news, spiegel, emacs-devel Since annotating is a somewhat time consuming activity, I don't mind (actually I prefer) having to type two keys to "annotate another version." So I suggest using M-n, M-p, and M-a. M-a is a standard Emacs command that is useful in most modes. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-14 15:45 ` Richard Stallman @ 2004-01-14 21:55 ` Kim F. Storm 2004-01-15 19:58 ` Andre Spiegel 2004-01-16 10:40 ` Richard Stallman 0 siblings, 2 replies; 43+ messages in thread From: Kim F. Storm @ 2004-01-14 21:55 UTC (permalink / raw) Cc: brutt+news, spiegel, emacs-devel Richard Stallman <rms@gnu.org> writes: > Since annotating is a somewhat time consuming activity, I don't mind > (actually I prefer) having to type two keys to "annotate another > version." > > So I suggest using M-n, M-p, and M-a. > > M-a is a standard Emacs command that is useful in most modes. What about N, P, and A ? They do not conflict with any commands in view mode. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-14 21:55 ` Kim F. Storm @ 2004-01-15 19:58 ` Andre Spiegel 2004-01-16 10:40 ` Richard Stallman 1 sibling, 0 replies; 43+ messages in thread From: Andre Spiegel @ 2004-01-15 19:58 UTC (permalink / raw) Cc: brutt+news, rms, emacs-devel On Wed, 2004-01-14 at 22:55, Kim F. Storm wrote: > What about N, P, and A ? They do not conflict with any commands in view mode. Fine with me. Those keys "feel" a little non-standard, but I guess that's what you get when you don't want to clash with any standard bindings :-) ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-14 21:55 ` Kim F. Storm 2004-01-15 19:58 ` Andre Spiegel @ 2004-01-16 10:40 ` Richard Stallman 2004-01-16 16:30 ` Kim F. Storm 1 sibling, 1 reply; 43+ messages in thread From: Richard Stallman @ 2004-01-16 10:40 UTC (permalink / raw) Cc: brutt+news, spiegel, emacs-devel > M-a is a standard Emacs command that is useful in most modes. What about N, P, and A ? They do not conflict with any commands in view mode. In a view-mode buffer it is reasonable to use them. Do you mean upper case letters, or lower case? ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-16 10:40 ` Richard Stallman @ 2004-01-16 16:30 ` Kim F. Storm 2004-01-17 12:55 ` Richard Stallman 0 siblings, 1 reply; 43+ messages in thread From: Kim F. Storm @ 2004-01-16 16:30 UTC (permalink / raw) Cc: brutt+news, spiegel, emacs-devel Richard Stallman <rms@gnu.org> writes: > > M-a is a standard Emacs command that is useful in most modes. > > What about N, P, and A ? They do not conflict with any commands in view mode. > > In a view-mode buffer it is reasonable to use them. > Do you mean upper case letters, or lower case? I meant the upper case letters -- I think that the effect and potentially long time to execute these commands justify NOT to have them bound to a lower case key. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-16 16:30 ` Kim F. Storm @ 2004-01-17 12:55 ` Richard Stallman 2004-01-17 21:34 ` Benjamin Rutt 0 siblings, 1 reply; 43+ messages in thread From: Richard Stallman @ 2004-01-17 12:55 UTC (permalink / raw) Cc: brutt+news, spiegel, emacs-devel > What about N, P, and A ? They do not conflict with any commands in view mode. > > In a view-mode buffer it is reasonable to use them. > Do you mean upper case letters, or lower case? I meant the upper case letters -- I think that the effect and potentially long time to execute these commands justify NOT to have them bound to a lower case key. I see View mode already defines some upper case letters. So it seems ok for a modified version of View mode, which this is, to define some more upper case letters. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-17 12:55 ` Richard Stallman @ 2004-01-17 21:34 ` Benjamin Rutt 2004-01-19 13:33 ` Andre Spiegel 0 siblings, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-17 21:34 UTC (permalink / raw) Cc: emacs-devel, spiegel, Kim F. Storm Richard Stallman <rms@gnu.org> writes: > I see View mode already defines some upper case letters. > So it seems ok for a modified version of View mode, which this is, > to define some more upper case letters. Now that it seems like everyone has reached agreement on the key bindings, here is the latest patch. Here are the new key bindings, and the new commands (FYI, I've implemented two new commands, "show revision comment log" and "show diff"): (define-key vc-annotate-mode-map "A" 'vc-annotate-revision-previous-to-line) (define-key vc-annotate-mode-map "D" 'vc-annotate-show-diff-revision-at-line) (define-key vc-annotate-mode-map "J" 'vc-annotate-revision-at-line) (define-key vc-annotate-mode-map "L" 'vc-annotate-show-log-revision-at-line) (define-key vc-annotate-mode-map "N" 'vc-annotate-next-version) (define-key vc-annotate-mode-map "P" 'vc-annotate-prev-version) One problem, I'm getting "Cyclic keymap inheritance" errors when I access the menu items with a mouse, maybe someone else can explain what is going on there, I don't know how to debug that any further. Other than that, I think the code is stable, and vc-annotate-mode now inherits from view-mode, as some of you requested. Comments appreciated. Thanks, Benjamin Rutt --- vc.el.orig 2004-01-10 21:51:37.000000000 -0500 +++ vc.el 2004-01-17 16:27:26.000000000 -0500 @@ -347,6 +347,25 @@ ;; time with hours, minutes, and seconds included. Probably safe to ;; ignore. Return the current-time, in units of fractional days. ;; +;; - annotate-extract-revision-at-line () +;; +;; Only required if `annotate-command' is defined for the backend. +;; Invoked from a buffer in vc-annotate-mode, return the revision +;; corresponding to the current line, or nil if there is no revision +;; corresponding to the current line. +;; +;; - decrement-revision (file rev) +;; +;; Only required if `annotate-command' is defined for the backend. +;; Return the revision previous to `rev', which is a string, for +;; file `file'. If there is no previous revision, return nil. +;; +;; - increment-revision (file rev) +;; +;; Only required if `annotate-command' is defined for the backend. +;; Return the revision after `rev', which is a string, for +;; file `file'. If there is no later revision, return nil. +;; ;; SNAPSHOT SYSTEM ;; ;; - create-snapshot (dir name branchp) @@ -631,6 +650,13 @@ m) "Local keymap used for VC-Annotate mode.") +(define-key vc-annotate-mode-map "A" 'vc-annotate-revision-previous-to-line) +(define-key vc-annotate-mode-map "D" 'vc-annotate-show-diff-revision-at-line) +(define-key vc-annotate-mode-map "J" 'vc-annotate-revision-at-line) +(define-key vc-annotate-mode-map "L" 'vc-annotate-show-log-revision-at-line) +(define-key vc-annotate-mode-map "N" 'vc-annotate-next-version) +(define-key vc-annotate-mode-map "P" 'vc-annotate-prev-version) + (defvar vc-annotate-mode-menu nil "Local keymap used for VC-Annotate mode's menu bar menu.") @@ -2285,11 +2311,12 @@ ;; Miscellaneous other entry points ;;;###autoload -(defun vc-print-log () +(defun vc-print-log (&optional focus-rev) "List the change log of the current buffer in a window." (interactive) (vc-ensure-vc-buffer) (let ((file buffer-file-name)) + (or focus-rev (setq focus-rev (vc-workfile-version file))) (vc-call print-log file) (set-buffer "*vc*") (pop-to-buffer (current-buffer)) @@ -2307,7 +2334,7 @@ ;; move point to the log entry for the current version (vc-call-backend ',(vc-backend file) 'show-log-entry - ',(vc-workfile-version file)) + ',focus-rev) (set-buffer-modified-p nil))))) (defun vc-default-show-log-entry (backend rev) @@ -2778,6 +2805,14 @@ (defvar vc-annotate-ratio nil "Global variable.") (defvar vc-annotate-backend nil "Global variable.") +;; internal buffer-local variables +(defvar vc-annotate-parent-file nil) +(defvar vc-annotate-parent-rev nil) +(defvar vc-annotate-parent-display-mode nil) +(make-local-variable 'vc-annotate-parent-file) +(make-local-variable 'vc-annotate-parent-rev) +(make-local-variable 'vc-annotate-parent-display-mode) + (defconst vc-annotate-font-lock-keywords ;; The fontification is done by vc-annotate-lines instead of font-lock. '((vc-annotate-lines))) @@ -2788,7 +2823,7 @@ `vc-annotate-buffers'." (cdr (assoc buffer vc-annotate-buffers))) -(define-derived-mode vc-annotate-mode fundamental-mode "Annotate" +(define-derived-mode vc-annotate-mode view-mode "Annotate" "Major mode for output buffers of the `vc-annotate' command. You can use the mode-specific menu to alter the time-span of the used @@ -2885,7 +2920,21 @@ (unless (eq vc-annotate-display-mode 'fullscale) (vc-annotate-display-select nil 'fullscale)) :style toggle :selected - (eq vc-annotate-display-mode 'fullscale)]))) + (eq vc-annotate-display-mode 'fullscale)]) + (list "--") + (list ["Annotate previous revision" + (vc-annotate-prev-version)]) + (list ["Annotate next revision" + (vc-annotate-next-version)]) + (list ["Annotate revision at line" + (vc-annotate-revision-at-line)]) + (list ["Annotate revision previous to line" + (vc-annotate-revision-previous-to-line)]) + (list ["Show log of version at line" + (vc-annotate-show-log-revision-at-line)]) + (list ["Show diff of version at line" + (vc-annotate-show-diff-revision-at-line)]))) + ;; Define the menu (if (or (featurep 'easymenu) (load "easymenu" t)) (easy-menu-define vc-annotate-mode-menu vc-annotate-mode-map @@ -2922,7 +2971,7 @@ ;;;; the contents in BUFFER. ;;;###autoload -(defun vc-annotate (prefix) +(defun vc-annotate (prefix &optional revision display-mode) "Display the edit history of the current file using colours. This command creates a buffer that shows, for each line of the current @@ -2949,19 +2998,24 @@ colors. `vc-annotate-background' specifies the background color." (interactive "P") (vc-ensure-vc-buffer) - (let* ((temp-buffer-name (concat "*Annotate " (buffer-name) "*")) + (let* ((temp-buffer-name nil) (temp-buffer-show-function 'vc-annotate-display-select) - (rev (vc-workfile-version buffer-file-name)) + (rev (or revision (vc-workfile-version buffer-file-name))) + (bfn buffer-file-name) (vc-annotate-version - (if prefix (read-string - (format "Annotate from version: (default %s) " rev) - nil nil rev) - rev))) - (if prefix - (setq vc-annotate-display-mode - (float (string-to-number - (read-string "Annotate span days: (default 20) " - nil nil "20"))))) + (if prefix (read-string + (format "Annotate from version: (default %s) " rev) + nil nil rev) + rev))) + (if display-mode + (setq vc-annotate-display-mode display-mode) + (if prefix + (setq vc-annotate-display-mode + (float (string-to-number + (read-string "Annotate span days: (default 20) " + nil nil "20")))))) + (setq temp-buffer-name (format "*Annotate %s (rev %s)*" + (buffer-name) vc-annotate-version)) (setq vc-annotate-backend (vc-backend buffer-file-name)) (message "Annotating...") (if (not (vc-find-backend-function vc-annotate-backend 'annotate-command)) @@ -2972,6 +3026,12 @@ buffer-file-name (get-buffer temp-buffer-name) vc-annotate-version)) + (save-excursion + (set-buffer temp-buffer-name) + (setq vc-annotate-parent-file bfn) + (setq vc-annotate-parent-rev vc-annotate-version) + (setq vc-annotate-parent-display-mode vc-annotate-display-mode)) + ;; Don't use the temp-buffer-name until the buffer is created ;; (only after `with-output-to-temp-buffer'.) (setq vc-annotate-buffers @@ -2979,6 +3039,155 @@ (list (cons (get-buffer temp-buffer-name) vc-annotate-backend)))) (message "Annotating... done"))) +(defun vc-annotate-prev-version (prefix) + "Visit the annotation of the version previous to this one. +With a numeric prefix argument, annotate the version that many +versions previous." + (interactive "p") + (vc-annotate-warp-version (- 0 prefix))) + +(defun vc-annotate-next-version (prefix) + "Visit the annotation of the version after this one. +With a numeric prefix argument, annotate the version that many +versions after." + (interactive "p") + (vc-annotate-warp-version prefix)) + +(defun vc-annotate-decrement-revision (file rev) + (setq vc-annotate-backend (vc-backend file)) + (vc-call-backend vc-annotate-backend 'decrement-revision file rev)) + +(defun vc-annotate-increment-revision (file rev) + (setq vc-annotate-backend (vc-backend file)) + (vc-call-backend vc-annotate-backend 'increment-revision file rev)) + +;; must be invoked from a buffer in vc-annotate-mode +(defun vc-annotate-extract-revision-at-line () + ;; visit parent buffer + (save-window-excursion + (vc-ensure-vc-buffer) + (setq vc-annotate-backend (vc-backend buffer-file-name))) + (vc-call-backend vc-annotate-backend 'annotate-extract-revision-at-line)) + +(defun vc-annotate-revision-at-line () + "From a buffer in vc-annotate-mode, replace the current +annotation with an annotation of the revision identified by the +version number displayed in this line." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer!") + (let ((rev-at-line (vc-annotate-extract-revision-at-line))) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (if (equal rev-at-line vc-annotate-parent-rev) + (message "Already at version %s" rev-at-line) + (vc-annotate-warp-version rev-at-line)))))) + +(defun vc-annotate-revision-previous-to-line () + "From a buffer in vc-annotate-mode, replace the current +annotation with an annotation of the revision previous to the one +identified by the version number displayed in this line." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer!") + (let ((rev-at-line (vc-annotate-extract-revision-at-line)) + (prev-rev nil)) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (setq prev-rev + (vc-annotate-decrement-revision + vc-annotate-parent-file + rev-at-line)) + (vc-annotate-warp-version prev-rev))))) + +(defun vc-annotate-show-log-revision-at-line () + "From a buffer in vc-annotate-mode, show the VC log of the +revision identified by the version number displayed in this line." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer!") + (let ((rev-at-line (vc-annotate-extract-revision-at-line))) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (vc-print-log rev-at-line))))) + +(defun vc-annotate-show-diff-revision-at-line () + "From a buffer in vc-annotate-mode, show the diff of the +revision identified by the version number displayed in this line +from the revision previous to it." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer!") + (let ((rev-at-line (vc-annotate-extract-revision-at-line)) + (prev-rev nil)) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (setq prev-rev + (vc-annotate-decrement-revision + vc-annotate-parent-file + rev-at-line)) + (if (not prev-rev) + (message "Cannot diff from any version prior to %s" rev-at-line) + (save-window-excursion + (vc-version-diff vc-annotate-parent-file prev-rev rev-at-line)) + (switch-to-buffer "*vc-diff*")))))) + +(defun vc-current-line () + "Returns the current buffer's line number." + (let ((oldpoint (point)) start) + (save-excursion + (save-restriction + (goto-char (point-min)) + (widen) + (forward-line 0) + (setq start (point)) + (goto-char oldpoint) + (forward-line 0) + (1+ (count-lines (point-min) (point))))))) + +(defun vc-annotate-warp-version (revspec) + "If argument `revspec' is a positive integer, warp that many +versions forward, if possible, otherwise echo a warning message. +If `revspec' is a negative integer, warp that many versions +backward, if possible, otherwise echo a warning message. If +`revspec' is a string, then it describes a revision number, so +warp to that revision." + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer!") + (let* ((oldline (vc-current-line)) + (revspeccopy revspec) + (newrev nil)) + (cond + ((and (integerp revspec) (> revspec 0)) + (setq newrev vc-annotate-parent-rev) + (while (and (> revspec 0) newrev) + (setq newrev (vc-annotate-increment-revision + vc-annotate-parent-file newrev)) + (setq revspec (1- revspec))) + (if (not newrev) + (message "Cannot increment %d versions from version %s" + revspeccopy vc-annotate-parent-rev))) + ((and (integerp revspec) (< revspec 0)) + (setq newrev vc-annotate-parent-rev) + (while (and (< revspec 0) newrev) + (setq newrev (vc-annotate-decrement-revision + vc-annotate-parent-file newrev)) + (setq revspec (1+ revspec))) + (if (not newrev) + (message "Cannot decrement %d versions from version %s" + (- 0 revspeccopy) vc-annotate-parent-rev))) + ((stringp revspec) (setq newrev revspec)) + (t (error "invalid argument to vc-annotate-warp-version"))) + (when newrev + (save-window-excursion + (find-file vc-annotate-parent-file) + (vc-annotate nil newrev vc-annotate-parent-display-mode)) + (kill-buffer (current-buffer)) ;; kill the buffer we started from + (switch-to-buffer (car (car (last vc-annotate-buffers)))) + (goto-line (min oldline (progn (goto-char (point-max)) + (previous-line) + (vc-current-line)))))))) + (defun vc-annotate-car-last-cons (a-list) "Return car of last cons in association list A-LIST." (if (not (eq nil (cdr a-list))) --- vc-cvs.el.orig 2004-01-11 21:31:30.000000000 -0500 +++ vc-cvs.el 2004-01-12 13:29:49.000000000 -0500 @@ -625,6 +625,32 @@ (beginning-of-line nil) (vc-cvs-annotate-time)))))) +(defun vc-cvs-annotate-extract-revision-at-line () + (save-excursion + (beginning-of-line) + (if (re-search-forward "^\\([0-9]+\\.[0-9]+\\(\\.[0-9]+\\)*\\) +(" + (line-end-position) t) + (match-string-no-properties 1) + nil))) + +(defun vc-cvs-decrement-revision (file rev) + (let ((ls (split-string rev "\\."))) + (setq ls (nreverse ls)) + (if (string= (car ls) "1") + nil ;; return nil if the revision cannot be decremented any further + (setq ls (cons (int-to-string (1- (string-to-int (car ls)))) (cdr ls))) + (setq ls (nreverse ls)) + (mapconcat 'identity ls ".")))) + +(defun vc-cvs-increment-revision (file rev) + (if (string= rev (vc-workfile-version file)) + nil ;; return nil if the revision cannot be incremented any further + (let ((ls (split-string rev "\\."))) + (setq ls (nreverse ls)) + (setq ls (cons (int-to-string (1+ (string-to-int (car ls)))) (cdr ls))) + (setq ls (nreverse ls)) + (mapconcat 'identity ls ".")))) + ;;; ;;; Snapshot system ;;; ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-17 21:34 ` Benjamin Rutt @ 2004-01-19 13:33 ` Andre Spiegel 2004-01-19 20:39 ` Kai Grossjohann 2004-01-19 21:13 ` Benjamin Rutt 0 siblings, 2 replies; 43+ messages in thread From: Andre Spiegel @ 2004-01-19 13:33 UTC (permalink / raw) Cc: emacs-devel On Sat, 2004-01-17 at 22:34, Benjamin Rutt wrote: > Now that it seems like everyone has reached agreement on the key > bindings, here is the latest patch. Thanks, I'm really looking forward to getting this installed. A few minor points: We already have a backend-specific function vc-BACKEND-previous-version, which currently has a single default implementation, vc-default-previous-version in vc.el. It handles RCS/CVS revision numbers (it's used to provide the defaults for C-u C-x v =). Could you please take a look at that function and resolve the redundancy with vc-cvs-increment/decrement-revision in your code? The reconciled implementation should combine the behaviour of both previous functions. Please also put these functions into vc.el as defaults for all backends, because the RCS-style revision numbers are still common for most backends. I'm a bit puzzled by your function vc-current-line. I must admit that I'm totally clueless in this area, but is there really no simpler way to determine this? Surely, this problem must have occured elsewhere already. Anybody got a hint for us? +(defun vc-current-line () + "Returns the current buffer's line number." + (let ((oldpoint (point)) start) + (save-excursion + (save-restriction + (goto-char (point-min)) + (widen) + (forward-line 0) + (setq start (point)) + (goto-char oldpoint) + (forward-line 0) + (1+ (count-lines (point-min) (point))))))) Last point: The doc strings in your functions do not comply with the Emacs guidelines yet. Every function must have a doc string, and the first line must be a complete sentence of its own (in the imperative voice). Please see the corresponding sections in the Elisp manual. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-19 13:33 ` Andre Spiegel @ 2004-01-19 20:39 ` Kai Grossjohann 2004-01-19 20:54 ` Benjamin Rutt 2004-01-20 15:32 ` Stefan Monnier 2004-01-19 21:13 ` Benjamin Rutt 1 sibling, 2 replies; 43+ messages in thread From: Kai Grossjohann @ 2004-01-19 20:39 UTC (permalink / raw) Andre Spiegel <spiegel@gnu.org> writes: > I'm a bit puzzled by your function vc-current-line. I must admit that > I'm totally clueless in this area, but is there really no simpler way to > determine this? Surely, this problem must have occured elsewhere > already. Anybody got a hint for us? Wow, what-line uses the same logic, it seems. Kai ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-19 20:39 ` Kai Grossjohann @ 2004-01-19 20:54 ` Benjamin Rutt 2004-01-20 1:28 ` Kim F. Storm 2004-01-20 18:11 ` Kevin Rodgers 2004-01-20 15:32 ` Stefan Monnier 1 sibling, 2 replies; 43+ messages in thread From: Benjamin Rutt @ 2004-01-19 20:54 UTC (permalink / raw) Cc: emacs-devel Kai Grossjohann <kai@emptydomain.de> writes: > Andre Spiegel <spiegel@gnu.org> writes: > >> I'm a bit puzzled by your function vc-current-line. I must admit that >> I'm totally clueless in this area, but is there really no simpler way to >> determine this? Surely, this problem must have occured elsewhere >> already. Anybody got a hint for us? > > Wow, what-line uses the same logic, it seems. So maybe what-line could be modified to return a useful value, namely the line number as an integer? -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-19 20:54 ` Benjamin Rutt @ 2004-01-20 1:28 ` Kim F. Storm 2004-01-20 15:31 ` Richard Stallman 2004-01-20 18:11 ` Kevin Rodgers 1 sibling, 1 reply; 43+ messages in thread From: Kim F. Storm @ 2004-01-20 1:28 UTC (permalink / raw) Cc: Kai Grossjohann, emacs-devel Benjamin Rutt <brutt+news@bloomington.in.us> writes: > Kai Grossjohann <kai@emptydomain.de> writes: > > > Andre Spiegel <spiegel@gnu.org> writes: > > > >> I'm a bit puzzled by your function vc-current-line. I must admit that > >> I'm totally clueless in this area, but is there really no simpler way to > >> determine this? Surely, this problem must have occured elsewhere > >> already. Anybody got a hint for us? > > > > Wow, what-line uses the same logic, it seems. > > So maybe what-line could be modified to return a useful value, namely > the line number as an integer? I think we should make a line-at-pos function: (defun line-at-pos (&optional pos) "Return buffer line number and narrowed line number at position POS. If POS is nil, use current buffer location. Return value is line-number or a cons (line-number narrowed-line-number)." (let ((opoint (or pos (point))) start) (save-excursion (save-restriction (goto-char (point-min)) (widen) (forward-line 0) (setq start (point)) (goto-char opoint) (forward-line 0) (if (/= start (point-min)) (cons (1+ (count-lines (point-min) (point))) (1+ (count-lines start (point)))) (1+ (count-lines (point-min) (point)))))))) and then implement what-line in terms of this function: (defun what-line () "Print the current buffer line number and narrowed line number of point." (interactive) (let ((l (line-at-pos (point)))) (if (consp l) (message "line %d (narrowed line %d)" (car l) (cdr l)) (message "Line %d" l)))) -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 1:28 ` Kim F. Storm @ 2004-01-20 15:31 ` Richard Stallman 2004-01-21 11:26 ` Kim F. Storm 0 siblings, 1 reply; 43+ messages in thread From: Richard Stallman @ 2004-01-20 15:31 UTC (permalink / raw) Cc: brutt+news, kai, emacs-devel (defun line-at-pos (&optional pos) "Return buffer line number and narrowed line number at position POS. If POS is nil, use current buffer location. Return value is line-number or a cons (line-number narrowed-line-number)." I don't like that complex definition of the return value. It should be one or the other. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 15:31 ` Richard Stallman @ 2004-01-21 11:26 ` Kim F. Storm 2004-01-21 14:15 ` Stefan Monnier 0 siblings, 1 reply; 43+ messages in thread From: Kim F. Storm @ 2004-01-21 11:26 UTC (permalink / raw) Cc: brutt+news, kai, emacs-devel Richard Stallman <rms@gnu.org> writes: > (defun line-at-pos (&optional pos) > "Return buffer line number and narrowed line number at position POS. > If POS is nil, use current buffer location. > Return value is line-number or a cons (line-number narrowed-line-number)." > > I don't like that complex definition of the return value. > It should be one or the other. What about this version? (defun line-at-pos (&optional pos) "Return buffer line number and narrowed line number at position POS. If POS is nil, use current buffer location. Return value is a cons (line-number . narrowed-line-number)." (let ((opoint (or pos (point))) start) (save-excursion (save-restriction (goto-char (point-min)) (widen) (forward-line 0) (setq start (point)) (goto-char opoint) (forward-line 0) (let ((l1 (count-lines (point-min) start)) (l2 (count-lines start (point)))) (cons (+ l1 l2 1) (1+ l2))))))) (defun what-line () "Print the current buffer line number and narrowed line number of point." (interactive) (let ((l (line-at-pos (point)))) (if (/= (car l) (cdr l)) (message "line %d (narrowed line %d)" (car l) (cdr l)) (message "Line %d" (car l))))) It actually works faster by not counting the lines between start and point twice! -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-21 11:26 ` Kim F. Storm @ 2004-01-21 14:15 ` Stefan Monnier 2004-01-21 16:39 ` Kim F. Storm 0 siblings, 1 reply; 43+ messages in thread From: Stefan Monnier @ 2004-01-21 14:15 UTC (permalink / raw) Cc: brutt+news, kai, rms, emacs-devel > (defun line-at-pos (&optional pos) > "Return buffer line number and narrowed line number at position POS. > If POS is nil, use current buffer location. > Return value is a cons (line-number . narrowed-line-number)." I suggest to only return narrowed-line-number (i.e. ignore narrowing). After all, most/all functions are expected to ignore narrowing unless they specifically need to know about it. `what-line' can still make use of such a function by doing the widening itself like it used to (and use the same optimization you suggested). Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-21 14:15 ` Stefan Monnier @ 2004-01-21 16:39 ` Kim F. Storm 2004-01-21 18:38 ` Stefan Monnier ` (2 more replies) 0 siblings, 3 replies; 43+ messages in thread From: Kim F. Storm @ 2004-01-21 16:39 UTC (permalink / raw) Cc: brutt+news, kai, rms, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > > (defun line-at-pos (&optional pos) > > "Return buffer line number and narrowed line number at position POS. > > If POS is nil, use current buffer location. > > Return value is a cons (line-number . narrowed-line-number)." > > I suggest to only return narrowed-line-number (i.e. ignore narrowing). > After all, most/all functions are expected to ignore narrowing unless they > specifically need to know about it. > > `what-line' can still make use of such a function by doing the widening > itself like it used to (and use the same optimization you suggested). > How about this version? (defun line-at-pos (&optional pos start) "Return (narrowed) buffer line number at position POS. If POS is nil, use current buffer location. If START is non-nil, count lines from that buffer position, even if narrowing is in effect." (let ((opoint (or pos (point)))) (save-excursion (save-restriction (goto-char (point-min)) (widen) (if start (goto-char start)) (forward-line 0) (setq start (point)) (goto-char opoint) (forward-line 0) (1+ (count-lines start (point))))))) (defun what-line () "Print the current buffer line number and narrowed line number of point." (interactive) (let ((l1 (line-at-pos (point-min) 0)) (l2 (line-at-pos (point) (point-min)))) (if (> l1 1) (message "line %d (narrowed line %d)" (+ l1 l2 -1) l2) (message "Line %d" l2)))) -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-21 16:39 ` Kim F. Storm @ 2004-01-21 18:38 ` Stefan Monnier 2004-01-22 22:06 ` Kim F. Storm 2004-01-22 19:00 ` Richard Stallman 2004-01-23 2:02 ` Miles Bader 2 siblings, 1 reply; 43+ messages in thread From: Stefan Monnier @ 2004-01-21 18:38 UTC (permalink / raw) Cc: brutt+news, kai, rms, emacs-devel >> I suggest to only return narrowed-line-number (i.e. ignore narrowing). > How about this version? You obviously misunderstood my "ignore narrowing": By "code that ignores narrowing" I understand code that does not use widen, narrow, save-restriction, etc... I understand it can be misleading, but I don't know how else to say it. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-21 18:38 ` Stefan Monnier @ 2004-01-22 22:06 ` Kim F. Storm 2004-01-22 23:39 ` Andre Spiegel 0 siblings, 1 reply; 43+ messages in thread From: Kim F. Storm @ 2004-01-22 22:06 UTC (permalink / raw) Cc: brutt+news, kai, rms, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > >> I suggest to only return narrowed-line-number (i.e. ignore narrowing). > > How about this version? > > By "code that ignores narrowing" I understand code that does not use widen, > narrow, save-restriction, etc... I gave it another round, and by ignoring narrowing as you suggest, the solution is pretty elegant -- both line-at-pos and what-line. I just committed the new code to CVS. This also means that there is now a line-at-pos function which return the current line number. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-22 22:06 ` Kim F. Storm @ 2004-01-22 23:39 ` Andre Spiegel 2004-01-23 1:54 ` Benjamin Rutt 0 siblings, 1 reply; 43+ messages in thread From: Andre Spiegel @ 2004-01-22 23:39 UTC (permalink / raw) On Thu, 2004-01-22 at 23:06, Kim F. Storm wrote: > I just committed the new code to CVS. This also means that there is now a > line-at-pos function which return the current line number. I've just changed vc.el to use line-at-pos instead of vc-current-line. Thanks. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-22 23:39 ` Andre Spiegel @ 2004-01-23 1:54 ` Benjamin Rutt 0 siblings, 0 replies; 43+ messages in thread From: Benjamin Rutt @ 2004-01-23 1:54 UTC (permalink / raw) Cc: emacs-devel Andre Spiegel <spiegel@gnu.org> writes: > On Thu, 2004-01-22 at 23:06, Kim F. Storm wrote: > >> I just committed the new code to CVS. This also means that there is now a >> line-at-pos function which return the current line number. > > I've just changed vc.el to use line-at-pos instead of vc-current-line. > Thanks. Thank you for taking care of that for me. Could you also commit the following bugfix to my code? The bug showed up when you have multiple vc-annotate buffers open; I was using `make-local-variable' improperly; that is, it wasn't being evaluated in the buffer that actually needed the buffer-local variable (that being the annotate buffer). Thanks, Benjamin Rutt Index: vc.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/vc.el,v retrieving revision 1.364 diff -c -r1.364 vc.el *** vc.el 22 Jan 2004 23:34:33 -0000 1.364 --- vc.el 23 Jan 2004 01:53:05 -0000 *************** *** 2816,2824 **** (defvar vc-annotate-parent-file nil) (defvar vc-annotate-parent-rev nil) (defvar vc-annotate-parent-display-mode nil) - (make-local-variable 'vc-annotate-parent-file) - (make-local-variable 'vc-annotate-parent-rev) - (make-local-variable 'vc-annotate-parent-display-mode) (defconst vc-annotate-font-lock-keywords ;; The fontification is done by vc-annotate-lines instead of font-lock. --- 2816,2821 ---- *************** *** 3038,3046 **** vc-annotate-version)) (save-excursion (set-buffer temp-buffer-name) ! (setq vc-annotate-parent-file bfn) ! (setq vc-annotate-parent-rev vc-annotate-version) ! (setq vc-annotate-parent-display-mode vc-annotate-display-mode)) ;; Don't use the temp-buffer-name until the buffer is created ;; (only after `with-output-to-temp-buffer'.) --- 3035,3044 ---- vc-annotate-version)) (save-excursion (set-buffer temp-buffer-name) ! (set (make-local-variable 'vc-annotate-parent-file) bfn) ! (set (make-local-variable 'vc-annotate-parent-rev) vc-annotate-version) ! (set (make-local-variable 'vc-annotate-parent-display-mode) ! vc-annotate-display-mode)) ;; Don't use the temp-buffer-name until the buffer is created ;; (only after `with-output-to-temp-buffer'.) Index: ChangeLog =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/ChangeLog,v retrieving revision 1.5619 diff -c -r1.5619 ChangeLog *** ChangeLog 22 Jan 2004 23:37:46 -0000 1.5619 --- ChangeLog 23 Jan 2004 01:53:05 -0000 *************** *** 1,3 **** --- 1,8 ---- + 2004-01-22 Benjamin Rutt <brutt@bloomington.in.us> + + * vc.el (vc-annotate): Fix improper use of `make-local-variable' + at the top level of vc.el. + 2004-01-23 Andre Spiegel <spiegel@gnu.org> * vc.el (vc-current-line): Function removed. This is now done by ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-21 16:39 ` Kim F. Storm 2004-01-21 18:38 ` Stefan Monnier @ 2004-01-22 19:00 ` Richard Stallman 2004-01-23 2:02 ` Miles Bader 2 siblings, 0 replies; 43+ messages in thread From: Richard Stallman @ 2004-01-22 19:00 UTC (permalink / raw) Cc: brutt+news, kai, monnier, emacs-devel How about this version? (defun line-at-pos (&optional pos start) That is a clean interface. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-21 16:39 ` Kim F. Storm 2004-01-21 18:38 ` Stefan Monnier 2004-01-22 19:00 ` Richard Stallman @ 2004-01-23 2:02 ` Miles Bader 2004-02-07 2:06 ` Kim F. Storm 2 siblings, 1 reply; 43+ messages in thread From: Miles Bader @ 2004-01-23 2:02 UTC (permalink / raw) Cc: brutt+news, kai, emacs-devel, Stefan Monnier, rms storm@cua.dk (Kim F. Storm) writes: > (defun line-at-pos (&optional pos start) > "Return (narrowed) buffer line number at position POS. > If POS is nil, use current buffer location. > If START is non-nil, count lines from that buffer position, > even if narrowing is in effect." I like the functionality, but the name seems slightly ambiguous -- it suggests that it may actually return the line _contents_ instead. How about calling it just `line-number' (with the same arguments)? -Miles -- Yo mama's so fat when she gets on an elevator it HAS to go down. ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-23 2:02 ` Miles Bader @ 2004-02-07 2:06 ` Kim F. Storm 0 siblings, 0 replies; 43+ messages in thread From: Kim F. Storm @ 2004-02-07 2:06 UTC (permalink / raw) Cc: emacs-devel Miles Bader <miles@lsi.nec.co.jp> writes: > storm@cua.dk (Kim F. Storm) writes: > > (defun line-at-pos (&optional pos start) > > I like the functionality, but the name seems slightly ambiguous -- > it suggests that it may actually return the line _contents_ instead. > > How about calling it just `line-number' (with the same arguments)? I have just renamed it to line-number-at-pos (and changed the users). I also added an entry to NEWS and to the lispref. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-19 20:54 ` Benjamin Rutt 2004-01-20 1:28 ` Kim F. Storm @ 2004-01-20 18:11 ` Kevin Rodgers 1 sibling, 0 replies; 43+ messages in thread From: Kevin Rodgers @ 2004-01-20 18:11 UTC (permalink / raw) Benjamin Rutt wrote: > Kai Grossjohann <kai@emptydomain.de> writes: >>Wow, what-line uses the same logic, it seems. > > So maybe what-line could be modified to return a useful value, namely > the line number as an integer? Yes, yes, yes. -- Kevin Rodgers ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-19 20:39 ` Kai Grossjohann 2004-01-19 20:54 ` Benjamin Rutt @ 2004-01-20 15:32 ` Stefan Monnier 2004-01-20 16:45 ` Benjamin Rutt 1 sibling, 1 reply; 43+ messages in thread From: Stefan Monnier @ 2004-01-20 15:32 UTC (permalink / raw) Cc: emacs-devel >> I'm a bit puzzled by your function vc-current-line. I must admit that >> I'm totally clueless in this area, but is there really no simpler way to >> determine this? No. In Emacs, we use chars rather than lines usually. I think his patch should be changed to not use lines but use chars instead, so it'll be simpler. After all, char positions are just as likely to be more-or-less correct than line positions. Or you could preserve "relative position in the file" (/ (- (point) (point-min)) (- (point-max) (point-min))) instead. >> Surely, this problem must have occured elsewhere already. Of course: it's just not very frequent, so counting lines every once in a while seems to work well enough. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 15:32 ` Stefan Monnier @ 2004-01-20 16:45 ` Benjamin Rutt 2004-01-20 18:26 ` Stefan Monnier 0 siblings, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-20 16:45 UTC (permalink / raw) Cc: Kai Grossjohann, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > No. In Emacs, we use chars rather than lines usually. > I think his patch should be changed to not use lines but use chars instead, > so it'll be simpler. After all, char positions are just as likely to be > more-or-less correct than line positions. I feel that the one time when line positions would be "more correct" would be when there are only minor changes to a file during successive revisions. Then, you'll likely be able to spot what was added or dropped between revisions by going back (P) and forth (N) a few times, since the code where the line was on originally will probably move up or down only a bit. On the other hand, if we went with char positions, then how closely the point follows the original line would not be determined by how many lines were added, but rather the sum of the lengths of the lines added. Another drawback of using characters, let's say only a C string was shortened during a commit, e.g.: changing "someverylongstring..." to "hi", then point might change lines even though the total # of lines in the file didn't change. > Or you could preserve "relative position in the file" (/ (- (point) > (point-min)) (- (point-max) (point-min))) instead. If we went with "relative position in the file", it would likely be surprising if you were e.g. browsing revision 1.1 whose annotate buffer had only 10 lines, and you were on line 2 (still the "Annotations for foo.c" line), then you browsed forward a few revisions. If the file grew a lot by then, all of a sudden you'd be about 20% into the file, which could be a few hundred lines by that time. This discussion brings up another point: I'd also like to preserve the column, since the annotate buffer can be very wide (it's usually > 80 columns, even if the original source code is < 80 columns). If you've spend the energy to h-scroll to the right, then I don't think I should make you h-scroll again every time you browse another revision. -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 16:45 ` Benjamin Rutt @ 2004-01-20 18:26 ` Stefan Monnier 2004-01-20 20:10 ` Benjamin Rutt 0 siblings, 1 reply; 43+ messages in thread From: Stefan Monnier @ 2004-01-20 18:26 UTC (permalink / raw) Cc: Kai Grossjohann, emacs-devel > I feel that the one time when line positions would be "more correct" > would be when there are only minor changes to a file during successive > revisions. There's no perfect answer. Sometimes lines are better, sometimes chars are better. But chars are simpler to implement, so I recommend to use them. Another thing you might want to do is to look at the context rather than just buffer positions. This works as long as the text around point hasn't changed much. Or to go a step further do a diff between the old buffer and the new, so that if point was in a part of the tex that's unchanged, you can find the exact same spot and other wise, you can estimate where to go. But maybe this is way overkill ;-) ? > This discussion brings up another point: I'd also like to preserve > the column, since the annotate buffer can be very wide (it's usually > > 80 columns, even if the original source code is < 80 columns). If > you've spend the energy to h-scroll to the right, then I don't think I > should make you h-scroll again every time you browse another revision. Maybe you're lucky to work on small files whose RCS archive is stored locally, but at least in my situation `vc-annotate' is a command that only use when nothing else works because it takes ages to show up, so I don't see the point in having short keybindings for revision-navigation and don't see the point either is saving you from hitting C-e to display the other half of the buffer. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 18:26 ` Stefan Monnier @ 2004-01-20 20:10 ` Benjamin Rutt 0 siblings, 0 replies; 43+ messages in thread From: Benjamin Rutt @ 2004-01-20 20:10 UTC (permalink / raw) Cc: Kai Grossjohann, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > Another thing you might want to do is to look at the context rather > than just buffer positions. This works as long as the text around > point hasn't changed much. Or to go a step further do a diff > between the old buffer and the new, so that if point was in a part > of the tex that's unchanged, you can find the exact same spot and > other wise, you can estimate where to go. But maybe this is way > overkill ;-) ? Wow, I guess that would be superior, but I don't feel it's worth all the time spent debugging it and looking at the pathological cases for me to do it...if someone else wants to, though, please do. > Maybe you're lucky to work on small files whose RCS archive is > stored locally, but at least in my situation `vc-annotate' is a > command that only use when nothing else works because it takes ages > to show up, so I don't see the point in having short keybindings for > revision-navigation and don't see the point either is saving you > from hitting C-e to display the other half of the buffer. Do you mind if I implement column preservation? (In other words, do you need a variable `vc-annotate-warp-preserve-column' so you can set it to nil?) I believe column preservation is useful, and will save me time since I plan on using the annotate browse often. (Most of my files are of average size, I guess, but I often develop using CVS over ssh where the remote host is one network hop away, so it's still quite fast in that case). -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-19 13:33 ` Andre Spiegel 2004-01-19 20:39 ` Kai Grossjohann @ 2004-01-19 21:13 ` Benjamin Rutt 2004-01-20 17:58 ` Andre Spiegel 1 sibling, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-19 21:13 UTC (permalink / raw) Cc: emacs-devel Thanks for the feedback, I've implemented your changes (I think :). Andre Spiegel <spiegel@gnu.org> writes: > A few minor points: We already have a backend-specific function > vc-BACKEND-previous-version, which currently has a single default > implementation, vc-default-previous-version in vc.el. It handles > RCS/CVS revision numbers (it's used to provide the defaults for C-u C-x > v =). > > Could you please take a look at that function and resolve the redundancy > with vc-cvs-increment/decrement-revision in your code? The reconciled > implementation should combine the behaviour of both previous functions. > Please also put these functions into vc.el as defaults for all backends, > because the RCS-style revision numbers are still common for most > backends. Done, I've eliminated my function vc-cvs-increment/decrement-revision, and added a vc-default-next-version. > I'm a bit puzzled by your function vc-current-line. I must admit that > I'm totally clueless in this area, but is there really no simpler way to > determine this? Surely, this problem must have occured elsewhere > already. Anybody got a hint for us? If someone could patch what-line in the manner I've suggested (just now) on this thread, I'll definitely eliminate my function vc-current-line; it does seem redundant. > Last point: The doc strings in your functions do not comply with the > Emacs guidelines yet. Every function must have a doc string, and the > first line must be a complete sentence of its own (in the imperative > voice). Please see the corresponding sections in the Elisp manual. Done, I think. Let me know if there are still any problems. I've also added docs to etc/NEWS, man/emacs.texi and lisp/ChangeLog. In addition, the function vc-annotate-workfile-version is new with this patch, useful when you've used 'P' to go back in time and want to go back to the latest version. Let me know of any feedback you may have. Here begins the patch (this time, I used 'cvs diff' to do the diffs): Index: etc/NEWS =================================================================== RCS file: /cvsroot/emacs/emacs/etc/NEWS,v retrieving revision 1.891 diff -u -r1.891 NEWS --- etc/NEWS 18 Jan 2004 20:26:39 -0000 1.891 +++ etc/NEWS 19 Jan 2004 20:57:40 -0000 @@ -1549,6 +1549,20 @@ Meta and Alt: (setq x-alt-keysym 'meta) (setq x-meta-keysym 'alt) + +** vc-annotate-mode enhancements + +In vc-annotate mode, you can now use the following key bindings for +enhanced functionality to browse the annotations of past revisions, or +to view diffs or log entries directly from vc-annotate-mode: + + P: annotates the previous revision + N: annotates the next revision + J: annotates the revision at line + A: annotates the revision previous to line + D: shows the diff of the revision at line with its previous revision + L: shows the log of the revision at line + W: annotates the workfile (most up to date) version \f * New modes and packages in 21.4 Index: lisp/ChangeLog =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/ChangeLog,v retrieving revision 1.5605 diff -u -r1.5605 ChangeLog --- lisp/ChangeLog 18 Jan 2004 14:11:11 -0000 1.5605 +++ lisp/ChangeLog 19 Jan 2004 20:57:40 -0000 @@ -1,3 +1,25 @@ +2004-01-19 Benjamin Rutt <brutt@bloomington.in.us> + + * vc.el (vc-default-previous-version): Doc enhancement. + (vc-default-next-version): New function. + (vc-print-log): New arg FOCUS-REV. + (vc-annotate-mode): Derives from view-mode now. + (vc-annotate): New args REVISION, DISPLAY-MODE. + (vc-annotate-prev-version): New function. + (vc-annotate-prev-version): New function. + (vc-annotate-next-version): New function. + (vc-annotate-workfile-version): New function. + (vc-annotate-extract-revision-at-line): New function. + (vc-annotate-revision-at-line): New function. + (vc-annotate-revision-previous-to-line): New function. + (vc-annotate-show-log-revision-at-line): New function. + (vc-annotate-show-diff-revision-at-line): New function. + (vc-current-line): New function. + (vc-annotate-warp-version): New function. + + * vc-cvs.el (vc-cvs-annotate-extract-revision-at-line): New + function. + 2004-01-18 Jesper Harder <harder@ifa.au.dk> * mail/smtpmail.el (smtpmail-send-data): Don't append spurious Index: lisp/vc-cvs.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/vc-cvs.el,v retrieving revision 1.66 diff -u -r1.66 vc-cvs.el --- lisp/vc-cvs.el 1 Oct 2003 13:22:53 -0000 1.66 +++ lisp/vc-cvs.el 19 Jan 2004 20:57:41 -0000 @@ -625,6 +625,14 @@ (beginning-of-line nil) (vc-cvs-annotate-time)))))) +(defun vc-cvs-annotate-extract-revision-at-line () + (save-excursion + (beginning-of-line) + (if (re-search-forward "^\\([0-9]+\\.[0-9]+\\(\\.[0-9]+\\)*\\) +(" + (line-end-position) t) + (match-string-no-properties 1) + nil))) + ;;; ;;; Snapshot system ;;; Index: lisp/vc.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/vc.el,v retrieving revision 1.361 diff -u -r1.361 vc.el --- lisp/vc.el 24 Dec 2003 23:18:10 -0000 1.361 +++ lisp/vc.el 19 Jan 2004 20:57:41 -0000 @@ -347,6 +347,13 @@ ;; time with hours, minutes, and seconds included. Probably safe to ;; ignore. Return the current-time, in units of fractional days. ;; +;; - annotate-extract-revision-at-line () +;; +;; Only required if `annotate-command' is defined for the backend. +;; Invoked from a buffer in vc-annotate-mode, return the revision +;; corresponding to the current line, or nil if there is no revision +;; corresponding to the current line. +;; ;; SNAPSHOT SYSTEM ;; ;; - create-snapshot (dir name branchp) @@ -392,7 +399,13 @@ ;; ;; - previous-version (file rev) ;; -;; Return the version number that precedes REV for FILE. +;; Return the version number that precedes REV for FILE, or nil if no such +;; version exists. +;; +;; - next-version (file rev) +;; +;; Return the version number that follows REV for FILE, or nil if no such +;; version exists. ;; ;; - check-headers () ;; @@ -631,6 +644,14 @@ m) "Local keymap used for VC-Annotate mode.") +(define-key vc-annotate-mode-map "A" 'vc-annotate-revision-previous-to-line) +(define-key vc-annotate-mode-map "D" 'vc-annotate-show-diff-revision-at-line) +(define-key vc-annotate-mode-map "J" 'vc-annotate-revision-at-line) +(define-key vc-annotate-mode-map "L" 'vc-annotate-show-log-revision-at-line) +(define-key vc-annotate-mode-map "N" 'vc-annotate-next-version) +(define-key vc-annotate-mode-map "P" 'vc-annotate-prev-version) +(define-key vc-annotate-mode-map "W" 'vc-annotate-workfile-version) + (defvar vc-annotate-mode-menu nil "Local keymap used for VC-Annotate mode's menu bar menu.") @@ -714,9 +735,10 @@ (substring rev (match-beginning 0) (match-end 0))) (defun vc-default-previous-version (backend file rev) - "Guess the version number immediately preceding REV for FILE. -This default implementation works for <major>.<minor>-style version numbers -as used by RCS and CVS." + "Return the version number immediately preceding REV for FILE, +or nil if there is no previous version. This default +implementation works for <major>.<minor>-style version numbers as +used by RCS and CVS." (let ((branch (vc-branch-part rev)) (minor-num (string-to-number (vc-minor-part rev)))) (when branch @@ -731,6 +753,16 @@ ;; return version of starting point (vc-branch-part branch)))))) +(defun vc-default-next-version (backend file rev) + "Return the version number immediately following REV for FILE, +or nil if there is no next version. This default implementation +works for <major>.<minor>-style version numbers as used by RCS +and CVS." + (when (not (string= rev (vc-workfile-version file))) + (let ((branch (vc-branch-part rev)) + (minor-num (string-to-number (vc-minor-part rev)))) + (concat branch "." (number-to-string (1+ minor-num)))))) + ;; File property caching (defun vc-clear-context () @@ -2285,11 +2317,13 @@ ;; Miscellaneous other entry points ;;;###autoload -(defun vc-print-log () - "List the change log of the current buffer in a window." +(defun vc-print-log (&optional focus-rev) + "List the change log of the current buffer in a window. If +FOCUS-REV is non-nil, leave the point at that revision." (interactive) (vc-ensure-vc-buffer) (let ((file buffer-file-name)) + (or focus-rev (setq focus-rev (vc-workfile-version file))) (vc-call print-log file) (set-buffer "*vc*") (pop-to-buffer (current-buffer)) @@ -2307,7 +2341,7 @@ ;; move point to the log entry for the current version (vc-call-backend ',(vc-backend file) 'show-log-entry - ',(vc-workfile-version file)) + ',focus-rev) (set-buffer-modified-p nil))))) (defun vc-default-show-log-entry (backend rev) @@ -2778,6 +2812,14 @@ (defvar vc-annotate-ratio nil "Global variable.") (defvar vc-annotate-backend nil "Global variable.") +;; internal buffer-local variables +(defvar vc-annotate-parent-file nil) +(defvar vc-annotate-parent-rev nil) +(defvar vc-annotate-parent-display-mode nil) +(make-local-variable 'vc-annotate-parent-file) +(make-local-variable 'vc-annotate-parent-rev) +(make-local-variable 'vc-annotate-parent-display-mode) + (defconst vc-annotate-font-lock-keywords ;; The fontification is done by vc-annotate-lines instead of font-lock. '((vc-annotate-lines))) @@ -2788,7 +2830,7 @@ `vc-annotate-buffers'." (cdr (assoc buffer vc-annotate-buffers))) -(define-derived-mode vc-annotate-mode fundamental-mode "Annotate" +(define-derived-mode vc-annotate-mode view-mode "Annotate" "Major mode for output buffers of the `vc-annotate' command. You can use the mode-specific menu to alter the time-span of the used @@ -2885,7 +2927,23 @@ (unless (eq vc-annotate-display-mode 'fullscale) (vc-annotate-display-select nil 'fullscale)) :style toggle :selected - (eq vc-annotate-display-mode 'fullscale)]))) + (eq vc-annotate-display-mode 'fullscale)]) + (list "--") + (list ["Annotate previous revision" + (call-interactively 'vc-annotate-prev-version)]) + (list ["Annotate next revision" + (call-interactively 'vc-annotate-next-version)]) + (list ["Annotate revision at line" + (vc-annotate-revision-at-line)]) + (list ["Annotate revision previous to line" + (vc-annotate-revision-previous-to-line)]) + (list ["Annotate latest revision" + (vc-annotate-workfile-version)]) + (list ["Show log of revision at line" + (vc-annotate-show-log-revision-at-line)]) + (list ["Show diff of revision at line" + (vc-annotate-show-diff-revision-at-line)]))) + ;; Define the menu (if (or (featurep 'easymenu) (load "easymenu" t)) (easy-menu-define vc-annotate-mode-menu vc-annotate-mode-map @@ -2922,7 +2980,7 @@ ;;;; the contents in BUFFER. ;;;###autoload -(defun vc-annotate (prefix) +(defun vc-annotate (prefix &optional revision display-mode) "Display the edit history of the current file using colours. This command creates a buffer that shows, for each line of the current @@ -2949,19 +3007,24 @@ colors. `vc-annotate-background' specifies the background color." (interactive "P") (vc-ensure-vc-buffer) - (let* ((temp-buffer-name (concat "*Annotate " (buffer-name) "*")) + (let* ((temp-buffer-name nil) (temp-buffer-show-function 'vc-annotate-display-select) - (rev (vc-workfile-version buffer-file-name)) + (rev (or revision (vc-workfile-version buffer-file-name))) + (bfn buffer-file-name) (vc-annotate-version - (if prefix (read-string - (format "Annotate from version: (default %s) " rev) - nil nil rev) - rev))) - (if prefix - (setq vc-annotate-display-mode - (float (string-to-number - (read-string "Annotate span days: (default 20) " - nil nil "20"))))) + (if prefix (read-string + (format "Annotate from version: (default %s) " rev) + nil nil rev) + rev))) + (if display-mode + (setq vc-annotate-display-mode display-mode) + (if prefix + (setq vc-annotate-display-mode + (float (string-to-number + (read-string "Annotate span days: (default 20) " + nil nil "20")))))) + (setq temp-buffer-name (format "*Annotate %s (rev %s)*" + (buffer-name) vc-annotate-version)) (setq vc-annotate-backend (vc-backend buffer-file-name)) (message "Annotating...") (if (not (vc-find-backend-function vc-annotate-backend 'annotate-command)) @@ -2972,12 +3035,162 @@ buffer-file-name (get-buffer temp-buffer-name) vc-annotate-version)) + (save-excursion + (set-buffer temp-buffer-name) + (setq vc-annotate-parent-file bfn) + (setq vc-annotate-parent-rev vc-annotate-version) + (setq vc-annotate-parent-display-mode vc-annotate-display-mode)) + ;; Don't use the temp-buffer-name until the buffer is created ;; (only after `with-output-to-temp-buffer'.) (setq vc-annotate-buffers (append vc-annotate-buffers (list (cons (get-buffer temp-buffer-name) vc-annotate-backend)))) (message "Annotating... done"))) + +(defun vc-annotate-prev-version (prefix) + "Visit the annotation of the version previous to this one. + +With a numeric prefix argument, annotate the version that many +versions previous." + (interactive "p") + (vc-annotate-warp-version (- 0 prefix))) + +(defun vc-annotate-next-version (prefix) + "Visit the annotation of the version after this one. + +With a numeric prefix argument, annotate the version that many +versions after." + (interactive "p") + (vc-annotate-warp-version prefix)) + +(defun vc-annotate-workfile-version () + "Visit the annotation of the workfile version of this file." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer") + (let ((warp-rev (vc-workfile-version vc-annotate-parent-file))) + (if (equal warp-rev vc-annotate-parent-rev) + (message "Already at version %s" warp-rev) + (vc-annotate-warp-version warp-rev))))) + +(defun vc-annotate-extract-revision-at-line () + "Extract the revision number of the current line." + ;; This function must be invoked from a buffer in vc-annotate-mode + (save-window-excursion + (vc-ensure-vc-buffer) + (setq vc-annotate-backend (vc-backend buffer-file-name))) + (vc-call-backend vc-annotate-backend 'annotate-extract-revision-at-line)) + +(defun vc-annotate-revision-at-line () + "Visit the annotation of the version identified in the current line." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer") + (let ((rev-at-line (vc-annotate-extract-revision-at-line))) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (if (equal rev-at-line vc-annotate-parent-rev) + (message "Already at version %s" rev-at-line) + (vc-annotate-warp-version rev-at-line)))))) + +(defun vc-annotate-revision-previous-to-line () + "Visit the annotation of the version before the version at line." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer") + (let ((rev-at-line (vc-annotate-extract-revision-at-line)) + (prev-rev nil)) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (setq prev-rev + (vc-call previous-version vc-annotate-parent-file rev-at-line)) + (vc-annotate-warp-version prev-rev))))) + +(defun vc-annotate-show-log-revision-at-line () + "Visit the log of the version at line." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer") + (let ((rev-at-line (vc-annotate-extract-revision-at-line))) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (vc-print-log rev-at-line))))) + +(defun vc-annotate-show-diff-revision-at-line () + "Visit the diff of the version at line from its previous version." + (interactive) + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer") + (let ((rev-at-line (vc-annotate-extract-revision-at-line)) + (prev-rev nil)) + (if (not rev-at-line) + (message "Cannot extract revision number from the current line") + (setq prev-rev + (vc-call previous-version vc-annotate-parent-file rev-at-line)) + (if (not prev-rev) + (message "Cannot diff from any version prior to %s" rev-at-line) + (save-window-excursion + (vc-version-diff vc-annotate-parent-file prev-rev rev-at-line)) + (switch-to-buffer "*vc-diff*")))))) + +(defun vc-current-line () + "Return the current buffer's line number." + (let ((oldpoint (point)) start) + (save-excursion + (save-restriction + (goto-char (point-min)) + (widen) + (forward-line 0) + (setq start (point)) + (goto-char oldpoint) + (forward-line 0) + (1+ (count-lines (point-min) (point))))))) + +(defun vc-annotate-warp-version (revspec) + "Annotate the version described by REVSPEC. + +If REVSPEC is a positive integer, warp that many versions +forward, if possible, otherwise echo a warning message. If +REVSPEC is a negative integer, warp that many versions backward, +if possible, otherwise echo a warning message. If REVSPEC is a +string, then it describes a revision number, so warp to that +revision." + (if (not (equal major-mode 'vc-annotate-mode)) + (message "Cannot be invoked outside of a vc annotate buffer") + (let* ((oldline (vc-current-line)) + (revspeccopy revspec) + (newrev nil)) + (cond + ((and (integerp revspec) (> revspec 0)) + (setq newrev vc-annotate-parent-rev) + (while (and (> revspec 0) newrev) + (setq newrev (vc-call next-version + vc-annotate-parent-file newrev)) + (setq revspec (1- revspec))) + (if (not newrev) + (message "Cannot increment %d versions from version %s" + revspeccopy vc-annotate-parent-rev))) + ((and (integerp revspec) (< revspec 0)) + (setq newrev vc-annotate-parent-rev) + (while (and (< revspec 0) newrev) + (setq newrev (vc-call previous-version + vc-annotate-parent-file newrev)) + (setq revspec (1+ revspec))) + (if (not newrev) + (message "Cannot decrement %d versions from version %s" + (- 0 revspeccopy) vc-annotate-parent-rev))) + ((stringp revspec) (setq newrev revspec)) + (t (error "Invalid argument to vc-annotate-warp-version"))) + (when newrev + (save-window-excursion + (find-file vc-annotate-parent-file) + (vc-annotate nil newrev vc-annotate-parent-display-mode)) + (kill-buffer (current-buffer)) ;; kill the buffer we started from + (switch-to-buffer (car (car (last vc-annotate-buffers)))) + (goto-line (min oldline (progn (goto-char (point-max)) + (previous-line) + (vc-current-line)))))))) (defun vc-annotate-car-last-cons (a-list) "Return car of last cons in association list A-LIST." Index: man/files.texi =================================================================== RCS file: /cvsroot/emacs/emacs/man/files.texi,v retrieving revision 1.86 diff -u -r1.86 files.texi --- man/files.texi 3 Dec 2003 21:04:49 -0000 1.86 +++ man/files.texi 19 Jan 2004 20:57:42 -0000 @@ -1536,6 +1536,46 @@ stretch factor greater than 1 means the color range spans more than a year. +From the annotate buffer, you can use the following keys to browse the +annotations of past revisions, view diffs, or view log entries: + +@itemize @bullet + +@item +Pressing @kbd{P} annotates the previous revision. It also takes a +numeric prefix argument, so for example @kbd{C-u 10 P} would take you +back 10 revisions. + +@item +Pressing @kbd{N} annotates the next revision. It also takes a numeric +prefix argument, so for example @kbd{C-u 10 N} would take you forward +10 revisions. + +@item +Pressing @kbd{J} annotates the revision at line (as denoted by the +version number on the same line). + +@item +Pressing @kbd{A} annotates the revision previous to line (as denoted +by the version number on the same line). This is useful to see the +state the file was in before the change on the current line was made. + +@item +Pressing @kbd{D} shows the diff of the revision at line with its +previous revision. This is useful to see what actually changed when +the revision denoted on the current line was committed. + +@item +Pressing @kbd{L} shows the log of the revision at line. This is +useful to see the author's description of the changes that occured +when the revision denoted on the current line was committed. + +@item +Pressing @kbd{W} annotates the workfile (most up to date) version. If +you used @kbd{P} and @kbd{N} to browse to other revisions, use this +key to return to the latest version. +@end itemize + @node Secondary VC Commands @subsection The Secondary Commands of VC ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-19 21:13 ` Benjamin Rutt @ 2004-01-20 17:58 ` Andre Spiegel 2004-01-20 20:05 ` Benjamin Rutt 0 siblings, 1 reply; 43+ messages in thread From: Andre Spiegel @ 2004-01-20 17:58 UTC (permalink / raw) Cc: emacs-devel On Mon, 2004-01-19 at 22:13, Benjamin Rutt wrote: > Thanks for the feedback, I've implemented your changes (I think :). Thanks for the patch. It's installed now. (I think vc-current-line is good enough right now, since there isn't a much better way to do it, we might as well stay with it. I agree with your reasoning that the current-line number seems like the best way to keep track of the current position in this case.) However, I'm getting a "Cyclic keymap inheritance" error now when I try to use one of the old items from the VC-Annotate menu (Like "Span Oldest->Newest"). Could you have a look at that? ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 17:58 ` Andre Spiegel @ 2004-01-20 20:05 ` Benjamin Rutt 2004-01-20 20:33 ` Stefan Monnier 0 siblings, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-20 20:05 UTC (permalink / raw) Cc: emacs-devel Andre Spiegel <spiegel@gnu.org> writes: > However, I'm getting a "Cyclic keymap inheritance" error now when I try > to use one of the old items from the VC-Annotate menu (Like "Span > Oldest->Newest"). Could you have a look at that? I've looked, and can't figure out why. I'm lost in a sea of `set-keymap-parent', `define-derived-mode', `easy-menu-define', etc. I suggest you just eliminate the new menu definitions I added (and the "--" separator before them), unless someone else can debug this further. I just don't understand enough about keymaps (and how they relate to menus) to debug them. -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 20:05 ` Benjamin Rutt @ 2004-01-20 20:33 ` Stefan Monnier 2004-01-20 22:28 ` Benjamin Rutt 0 siblings, 1 reply; 43+ messages in thread From: Stefan Monnier @ 2004-01-20 20:33 UTC (permalink / raw) Cc: Andre Spiegel, emacs-devel > I've looked, and can't figure out why. I'm lost in a sea of > `set-keymap-parent', `define-derived-mode', `easy-menu-define', etc. > I suggest you just eliminate the new menu definitions I added (and the > "--" separator before them), unless someone else can debug this > further. I just don't understand enough about keymaps (and how they > relate to menus) to debug them. I strongly expect that the problem is in the fact that you use view-mode as parent even though it's not a major-mode. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 20:33 ` Stefan Monnier @ 2004-01-20 22:28 ` Benjamin Rutt 2004-01-22 23:20 ` Kevin Rodgers 0 siblings, 1 reply; 43+ messages in thread From: Benjamin Rutt @ 2004-01-20 22:28 UTC (permalink / raw) Cc: Andre Spiegel, emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > I strongly expect that the problem is in the fact that you use view-mode as > parent even though it's not a major-mode. Thanks for the tip, you are correct; I guess define-derived-mode was somewhat misleading to me since it doesn't mention anywhere in 'C-h f define-derived-mode' that it only works for major modes. Andre, could you install the following tiny patch that fixes the problem? Index: lisp/vc.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/vc.el,v retrieving revision 1.362 diff -u -r1.362 vc.el --- lisp/vc.el 20 Jan 2004 17:39:09 -0000 1.362 +++ lisp/vc.el 20 Jan 2004 22:25:47 -0000 @@ -2830,7 +2830,7 @@ `vc-annotate-buffers'." (cdr (assoc buffer vc-annotate-buffers))) -(define-derived-mode vc-annotate-mode view-mode "Annotate" +(define-derived-mode vc-annotate-mode fundamental-mode "Annotate" "Major mode for output buffers of the `vc-annotate' command. You can use the mode-specific menu to alter the time-span of the used @@ -2839,6 +2839,7 @@ (set (make-local-variable 'truncate-lines) t) (set (make-local-variable 'font-lock-defaults) '(vc-annotate-font-lock-keywords t)) + (view-mode 1) (vc-annotate-add-menu)) (defun vc-annotate-display-default (&optional ratio) -- Benjamin ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-20 22:28 ` Benjamin Rutt @ 2004-01-22 23:20 ` Kevin Rodgers 2004-01-22 23:40 ` Stefan Monnier 0 siblings, 1 reply; 43+ messages in thread From: Kevin Rodgers @ 2004-01-22 23:20 UTC (permalink / raw) Benjamin Rutt wrote: > Stefan Monnier <monnier@iro.umontreal.ca> writes: >>I strongly expect that the problem is in the fact that you use view-mode as >>parent even though it's not a major-mode. > > Thanks for the tip, you are correct; I guess define-derived-mode was > somewhat misleading to me since it doesn't mention anywhere in 'C-h f > define-derived-mode' that it only works for major modes. It would be nice if there was a major-mode-p predicate that define-derived-mode could use to verify its PARENT argument. -- Kevin Rodgers ^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] add interactive browse of revisions from vc *Annotate* buffers 2004-01-22 23:20 ` Kevin Rodgers @ 2004-01-22 23:40 ` Stefan Monnier 0 siblings, 0 replies; 43+ messages in thread From: Stefan Monnier @ 2004-01-22 23:40 UTC (permalink / raw) Cc: emacs-devel > It would be nice if there was a major-mode-p predicate that > define-derived-mode could use to verify its PARENT argument. I don't think it's worth the trouble. Stefan ^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2004-02-07 2:06 UTC | newest] Thread overview: 43+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-01-12 2:54 [patch] add interactive browse of revisions from vc *Annotate* buffers Benjamin Rutt 2004-01-12 5:30 ` Andre Spiegel 2004-01-12 11:06 ` Kim F. Storm 2004-01-12 13:58 ` Benjamin Rutt 2004-01-12 17:11 ` Kim F. Storm 2004-01-12 17:20 ` Benjamin Rutt 2004-01-12 20:09 ` Andre Spiegel 2004-01-12 20:35 ` Benjamin Rutt 2004-01-13 10:57 ` Kim F. Storm 2004-01-14 15:45 ` Richard Stallman 2004-01-14 21:55 ` Kim F. Storm 2004-01-15 19:58 ` Andre Spiegel 2004-01-16 10:40 ` Richard Stallman 2004-01-16 16:30 ` Kim F. Storm 2004-01-17 12:55 ` Richard Stallman 2004-01-17 21:34 ` Benjamin Rutt 2004-01-19 13:33 ` Andre Spiegel 2004-01-19 20:39 ` Kai Grossjohann 2004-01-19 20:54 ` Benjamin Rutt 2004-01-20 1:28 ` Kim F. Storm 2004-01-20 15:31 ` Richard Stallman 2004-01-21 11:26 ` Kim F. Storm 2004-01-21 14:15 ` Stefan Monnier 2004-01-21 16:39 ` Kim F. Storm 2004-01-21 18:38 ` Stefan Monnier 2004-01-22 22:06 ` Kim F. Storm 2004-01-22 23:39 ` Andre Spiegel 2004-01-23 1:54 ` Benjamin Rutt 2004-01-22 19:00 ` Richard Stallman 2004-01-23 2:02 ` Miles Bader 2004-02-07 2:06 ` Kim F. Storm 2004-01-20 18:11 ` Kevin Rodgers 2004-01-20 15:32 ` Stefan Monnier 2004-01-20 16:45 ` Benjamin Rutt 2004-01-20 18:26 ` Stefan Monnier 2004-01-20 20:10 ` Benjamin Rutt 2004-01-19 21:13 ` Benjamin Rutt 2004-01-20 17:58 ` Andre Spiegel 2004-01-20 20:05 ` Benjamin Rutt 2004-01-20 20:33 ` Stefan Monnier 2004-01-20 22:28 ` Benjamin Rutt 2004-01-22 23:20 ` Kevin Rodgers 2004-01-22 23:40 ` Stefan Monnier
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).