From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Tom Tromey Newsgroups: gmane.emacs.devel Subject: some vc-status updates Date: Tue, 08 Jan 2008 18:31:18 -0700 Message-ID: Reply-To: tromey@redhat.com NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1199844198 8490 80.91.229.12 (9 Jan 2008 02:03:18 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 9 Jan 2008 02:03:18 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Jan 09 03:03:37 2008 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1JCQI4-0005hh-VK for ged-emacs-devel@m.gmane.org; Wed, 09 Jan 2008 03:03:37 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JCQHg-0003WO-7C for ged-emacs-devel@m.gmane.org; Tue, 08 Jan 2008 21:03:12 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JCQHc-0003VQ-3c for emacs-devel@gnu.org; Tue, 08 Jan 2008 21:03:08 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JCQHY-0003VE-Hi for emacs-devel@gnu.org; Tue, 08 Jan 2008 21:03:06 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JCQHY-0003VB-BI for emacs-devel@gnu.org; Tue, 08 Jan 2008 21:03:04 -0500 Original-Received: from mx1.redhat.com ([66.187.233.31]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JCQHX-0002Uh-P0 for emacs-devel@gnu.org; Tue, 08 Jan 2008 21:03:04 -0500 Original-Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m09230RJ010670 for ; Tue, 8 Jan 2008 21:03:00 -0500 Original-Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m0922xsP026852 for ; Tue, 8 Jan 2008 21:02:59 -0500 Original-Received: from opsy.redhat.com (ton.yyz.redhat.com [10.15.16.15]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m0922wXI010813; Tue, 8 Jan 2008 21:02:59 -0500 Original-Received: by opsy.redhat.com (Postfix, from userid 500) id 83608508021; Tue, 8 Jan 2008 18:31:18 -0700 (MST) X-Attribution: Tom User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.990 (gnu/linux) X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:86610 Archived-At: This adds a bunch of functionality to vc-status. Most of the new stuff actually works :). A few notes: * I tried to register a new file with svn, but it failed. This was reported a few days ago but not fixed. * vc-diff does not work unless you have a file marked. Maybe vc-status-marked-files should return the current directory in this case? * vc-status-move-to-goal-column is a hack BTW ewoc is pretty nice. I think I will switch package.el to use it. Mostly this was an experiment, to see how easy it would be to turn vc-status into a pcvs replacement. It doesn't look super hard, I guess, though there is still a good amount to do. In particular: * Asynchronous operation * Updates. Can you do a full-directory update in VC? Or do we need another new backend method? * A new backend method for "ignore". * Saving buffers should probably update the vc-status buffer. * Maybe other places checking vc-dired-mode should check for vc-status-mode. Tom 2008-01-09 Tom Tromey * vc.el (vc-status-headers): Rename from vc-status-insert-headers. Just return header. (vc-status-move-to-goal-column): New function. (vc-status-mode-map): Define more keys. (vc-status-mode): Use vc-status-refresh. Now 'special. (vc-status-refresh): New function. (vc-status-next-line): Likewise. (vc-status-previous-line): Likewise. (vc-status-mark-file): Use vc-status-next-line. (vc-status-unmark-file): Use vc-status-previous-line. (vc-status-unmark-file-up): New function. (vc-status-register): Likewise. (vc-status-find-file): Likewise. (vc-status-find-file-other-window): Likewise. (vc-status-current-file): Likewise. (vc-ensure-vc-buffer): Understand vc-status mode. Index: vc.el =================================================================== RCS file: /sources/emacs/emacs/lisp/vc.el,v retrieving revision 1.508 diff -u -c -r1.508 vc.el cvs diff: conflicting specifications of output style *** vc.el 6 Jan 2008 16:02:38 -0000 1.508 --- vc.el 9 Jan 2008 01:56:25 -0000 *************** *** 1307,1314 **** (defun vc-ensure-vc-buffer () "Make sure that the current buffer visits a version-controlled file." ! (if vc-dired-mode ! (set-buffer (find-file-noselect (dired-get-filename))) (while (and vc-parent-buffer (buffer-live-p vc-parent-buffer) ;; Avoid infinite looping when vc-parent-buffer and --- 1307,1318 ---- (defun vc-ensure-vc-buffer () "Make sure that the current buffer visits a version-controlled file." ! (cond ! (vc-dired-mode ! (set-buffer (find-file-noselect (dired-get-filename)))) ! ((eq major-mode 'vc-status-mode) ! (set-buffer (find-file-noselect (vc-status-current-file)))) ! (t (while (and vc-parent-buffer (buffer-live-p vc-parent-buffer) ;; Avoid infinite looping when vc-parent-buffer and *************** *** 1318,1324 **** (if (not buffer-file-name) (error "Buffer %s is not associated with a file" (buffer-name)) (if (not (vc-backend buffer-file-name)) ! (error "File %s is not under version control" buffer-file-name))))) ;;; Support for the C-x v v command. This is where all the single-file-oriented ;;; code from before the fileset rewrite lives. --- 1322,1328 ---- (if (not buffer-file-name) (error "Buffer %s is not associated with a file" (buffer-name)) (if (not (vc-backend buffer-file-name)) ! (error "File %s is not under version control" buffer-file-name)))))) ;;; Support for the C-x v v command. This is where all the single-file-oriented ;;; code from before the fileset rewrite lives. *************** *** 2512,2530 **** (defvar vc-status nil) ! (defun vc-status-insert-headers (backend dir) ! (insert (format "VC backend :%s\n" backend)) ! (insert "Repository : The repository goes here\n") ! (insert (format "Working dir: %s\n\n\n" dir))) (defun vc-status-printer (fileentry) "Pretty print FILEENTRY." (insert (format "%c %-20s %s" (if (vc-status-fileinfo->marked fileentry) ?* ? ) (vc-status-fileinfo->state fileentry) (vc-status-fileinfo->name fileentry)))) (defun vc-status (dir) "Show the VC status for DIR." (interactive "DVC status for directory: ") --- 2518,2543 ---- (defvar vc-status nil) ! (defun vc-status-headers (backend dir) ! (concat ! (format "VC backend : %s\n" backend) ! "Repository : The repository goes here\n" ! (format "Working dir: %s\n" dir))) (defun vc-status-printer (fileentry) "Pretty print FILEENTRY." (insert + ;; If you change this, change vc-status-move-to-goal-column. (format "%c %-20s %s" (if (vc-status-fileinfo->marked fileentry) ?* ? ) (vc-status-fileinfo->state fileentry) (vc-status-fileinfo->name fileentry)))) + (defun vc-status-move-to-goal-column () + (beginning-of-line) + ;; Must be in sync with vc-status-printer. + (forward-char 25)) + (defun vc-status (dir) "Show the VC status for DIR." (interactive "DVC status for directory: ") *************** *** 2534,2542 **** (vc-status-mode)) (defvar vc-status-mode-map ! (let ((map (make-sparse-keymap))) (define-key map "m" 'vc-status-mark-file) (define-key map "u" 'vc-status-unmark-file) map) "Keymap for VC status") --- 2547,2576 ---- (vc-status-mode)) (defvar vc-status-mode-map ! (let ((map (make-keymap))) ! (suppress-keymap map) ! ;; Marking. (define-key map "m" 'vc-status-mark-file) (define-key map "u" 'vc-status-unmark-file) + (define-key map "\C-?" 'vc-status-unmark-file-up) + ;; Movement. + (define-key map "n" 'vc-status-next-line) + (define-key map " " 'vc-status-next-line) + (define-key map "\t" 'vc-status-next-line) + (define-key map "p" 'vc-status-previous-line) + (define-key map [backtab] 'vc-status-previous-line) + ;; VC commands. + (define-key map "=" 'vc-diff) + (define-key map "a" 'vc-status-register) + ;; Can't be "g" (as in vc map), so "A" for "Annotate". + (define-key map "A" 'vc-annotate) + ;; vc-print-log uses the current buffer, not a file. + ;; (define-key map "l" 'vc-status-print-log) + ;; The remainder. + (define-key map "f" 'vc-status-find-file) + (define-key map "o" 'vc-status-find-file-other-window) + (define-key map "q" 'bury-buffer) + (define-key map "g" 'vc-status-refresh) map) "Keymap for VC status") *************** *** 2552,2581 **** entries) (erase-buffer) (set (make-local-variable 'vc-status) ! (ewoc-create #'vc-status-printer)) ! (vc-status-insert-headers backend default-directory) ! (setq entries (vc-call-backend backend 'dir-status default-directory)) ! (dolist (entry entries) ! (ewoc-enter-last ! vc-status (vc-status-create-fileinfo (cdr entry) (car entry)))))) (defun vc-status-mark-file () ! "Mark the current file." (interactive) (let* ((crt (ewoc-locate vc-status)) (file (ewoc-data crt))) (setf (vc-status-fileinfo->marked file) t) (ewoc-invalidate vc-status crt) ! (ewoc-goto-next vc-status 1))) (defun vc-status-unmark-file () ! "Mark the current file." (interactive) (let* ((crt (ewoc-locate vc-status)) (file (ewoc-data crt))) (setf (vc-status-fileinfo->marked file) nil) (ewoc-invalidate vc-status crt) ! (ewoc-goto-next vc-status 1))) (defun vc-status-marked-files () "Return the list of marked files" --- 2586,2675 ---- entries) (erase-buffer) (set (make-local-variable 'vc-status) ! (ewoc-create #'vc-status-printer ! (vc-status-headers backend default-directory))) ! (vc-status-refresh))) ! ! (put 'vc-status-mode 'mode-class 'special) ! ! (defun vc-status-refresh () ! "Refresh the contents of the VC status buffer." ! (interactive) ! ;; This is not very efficient; ewoc could use a new function here. ! (ewoc-filter vc-status (lambda (node) nil)) ! (let ((backend (vc-responsible-backend default-directory))) ! (dolist (entry (vc-call-backend backend 'dir-status default-directory)) ! (ewoc-enter-last vc-status ! (vc-status-create-fileinfo (cdr entry) (car entry))))) ! (ewoc-goto-node vc-status (ewoc-nth vc-status 0))) ! ! (defun vc-status-next-line (arg) ! "Go to the next line. ! If a prefix argument is given, move by that many lines." ! (interactive "p") ! (ewoc-goto-next vc-status arg) ! (vc-status-move-to-goal-column)) ! ! (defun vc-status-previous-line (arg) ! "Go to the previous line. ! If a prefix argument is given, move by that many lines." ! (interactive "p") ! (ewoc-goto-prev vc-status arg) ! (vc-status-move-to-goal-column)) (defun vc-status-mark-file () ! "Mark the current file and move to the next line." (interactive) (let* ((crt (ewoc-locate vc-status)) (file (ewoc-data crt))) (setf (vc-status-fileinfo->marked file) t) (ewoc-invalidate vc-status crt) ! (vc-status-next-line 1))) (defun vc-status-unmark-file () ! "Unmark the current file and move to the next line." (interactive) (let* ((crt (ewoc-locate vc-status)) (file (ewoc-data crt))) (setf (vc-status-fileinfo->marked file) nil) (ewoc-invalidate vc-status crt) ! (vc-status-next-line 1))) ! ! (defun vc-status-unmark-file-up () ! "Move to the previous line and unmark the file." ! (interactive) ! ;; If we're on the first line, we won't move up, but we will still ! ;; remove the mark. This seems a bit odd but it is what buffer-menu ! ;; does. ! (let* ((prev (ewoc-goto-prev vc-status 1)) ! (file (ewoc-data prev))) ! (setf (vc-status-fileinfo->marked file) nil) ! (ewoc-invalidate vc-status prev) ! (vc-status-move-to-goal-column))) ! ! (defun vc-status-register () ! "Register the marked files, or the current file if no marks." ! (interactive) ! (let ((files (or (vc-status-marked-files) ! (list (vc-status-current-file))))) ! (dolist (file files) ! (vc-register file)))) ! ! (defun vc-status-find-file () ! "Find the file on the current line." ! (interactive) ! (find-file (vc-status-current-file))) ! ! (defun vc-status-find-file-other-window () ! "Find the file on the current line, in another window." ! (interactive) ! (find-file-other-window (vc-status-current-file))) ! ! (defun vc-status-current-file () ! (let ((node (ewoc-locate vc-status))) ! (unless node ! (error "No file available.")) ! (expand-file-name (vc-status-fileinfo->name (ewoc-data node))))) (defun vc-status-marked-files () "Return the list of marked files"