comparison lisp/vc.el @ 96203:30bbe1648bcf

* vc.el: * vc-hooks.el: * vc-dispatcher.el: Move vc-dir variables and functions ... * vc-dir.el: ... here. New file. * Makefile.in (ELCFILES): Add vc-dir.elc.
author Dan Nicolaescu <dann@ics.uci.edu>
date Sun, 22 Jun 2008 19:04:22 +0000
parents 2bd68cb03fe1
children ad9760e68890
comparison
equal deleted inserted replaced
96202:2bd68cb03fe1 96203:30bbe1648bcf
637 ;; files checked into git (but not all), using C-x v l to get a log file 637 ;; files checked into git (but not all), using C-x v l to get a log file
638 ;; from a file only present in git, and then typing RET on some log entry, 638 ;; from a file only present in git, and then typing RET on some log entry,
639 ;; vc will bombs out because it wants to see the file being in CVS. 639 ;; vc will bombs out because it wants to see the file being in CVS.
640 ;; Those logs should likely use a local variable to hardware the VC they 640 ;; Those logs should likely use a local variable to hardware the VC they
641 ;; are supposed to work with. 641 ;; are supposed to work with.
642 ;;
643 ;; - vc-dir-kill-dir-status-process should not be specific to dir-status,
644 ;; it should work for other async commands done through vc-do-command
645 ;; as well,
646 ;;
647 ;; - vc-dir toolbar needs more icons.
648 ;;
649 ;; - vc-dir-menu-map-filter hook call needs to be moved to vc.el.
642 ;; 650 ;;
643 ;;;; Problems: 651 ;;;; Problems:
644 ;; 652 ;;
645 ;; - the *vc-dir* buffer is not updated correctly anymore after VC 653 ;; - the *vc-dir* buffer is not updated correctly anymore after VC
646 ;; operations that change the file state. 654 ;; operations that change the file state.
884 (let ((buffer (or buffer (current-buffer)))) 892 (let ((buffer (or buffer (current-buffer))))
885 (cond ((derived-mode-p 'vc-dir-mode) t) 893 (cond ((derived-mode-p 'vc-dir-mode) t)
886 (vc-parent-buffer (vc-derived-from-dir-mode vc-parent-buffer)) 894 (vc-parent-buffer (vc-derived-from-dir-mode vc-parent-buffer))
887 (t nil)))) 895 (t nil))))
888 896
889 (defvar vc-dir-backend nil 897 (defvar vc-dir-backend)
890 "The backend used by the current *vc-dir* buffer.")
891 898
892 ;; FIXME: this is not functional, commented out. 899 ;; FIXME: this is not functional, commented out.
893 ;; (defun vc-deduce-fileset (&optional observer) 900 ;; (defun vc-deduce-fileset (&optional observer)
894 ;; "Deduce a set of files and a backend to which to apply an operation and 901 ;; "Deduce a set of files and a backend to which to apply an operation and
895 ;; the common state of the fileset. Return (BACKEND . FILESET)." 902 ;; the common state of the fileset. Return (BACKEND . FILESET)."
903 ;; (vc-responsible-backend default-directory) 910 ;; (vc-responsible-backend default-directory)
904 ;; (assert (and (= 1 (length raw)) 911 ;; (assert (and (= 1 (length raw))
905 ;; (not (file-directory-p (car raw))))) 912 ;; (not (file-directory-p (car raw)))))
906 ;; (vc-backend (car cooked))))) 913 ;; (vc-backend (car cooked)))))
907 ;; (cons backend selection))) 914 ;; (cons backend selection)))
915
916 (declare-function vc-dir-child-files "vc-dir" ())
917 (declare-function vc-dir-current-file "vc-dir" ())
918 (declare-function vc-dir-marked-files "vc-dir" ())
919 (declare-function vc-dir-marked-only-files "vc-dir" ())
908 920
909 (defun vc-deduce-fileset (&optional observer allow-unregistered only-files) 921 (defun vc-deduce-fileset (&optional observer allow-unregistered only-files)
910 "Deduce a set of files and a backend to which to apply an operation. 922 "Deduce a set of files and a backend to which to apply an operation.
911 923
912 Return (BACKEND FILESET FILESET-ONLY-FILES). 924 Return (BACKEND FILESET FILESET-ONLY-FILES).
1749 (message "File contains conflicts."))) 1761 (message "File contains conflicts.")))
1750 1762
1751 ;;;###autoload 1763 ;;;###autoload
1752 (defalias 'vc-resolve-conflicts 'smerge-ediff) 1764 (defalias 'vc-resolve-conflicts 'smerge-ediff)
1753 1765
1754 ;; VC status implementation
1755
1756 (defun vc-default-status-extra-headers (backend dir)
1757 ;; Be loud by default to remind people to add code to display
1758 ;; backend specific headers.
1759 ;; XXX: change this to return nil before the release.
1760 (concat
1761 (propertize "Extra : " 'face 'font-lock-type-face)
1762 (propertize "Please add backend specific headers here. It's easy!"
1763 'face 'font-lock-warning-face)))
1764
1765 (defun vc-dir-headers (backend dir)
1766 "Display the headers in the *VC dir* buffer.
1767 It calls the `status-extra-headers' backend method to display backend
1768 specific headers."
1769 (concat
1770 (propertize "VC backend : " 'face 'font-lock-type-face)
1771 (propertize (format "%s\n" backend) 'face 'font-lock-variable-name-face)
1772 (propertize "Working dir: " 'face 'font-lock-type-face)
1773 (propertize (format "%s\n" dir) 'face 'font-lock-variable-name-face)
1774 (vc-call-backend backend 'status-extra-headers dir)
1775 "\n"))
1776
1777 (defun vc-default-status-printer (backend fileentry)
1778 "Pretty print FILEENTRY."
1779 ;; If you change the layout here, change vc-dir-move-to-goal-column.
1780 (let* ((isdir (vc-dir-fileinfo->directory fileentry))
1781 (state (if isdir 'DIRECTORY (vc-dir-fileinfo->state fileentry)))
1782 (filename (vc-dir-fileinfo->name fileentry)))
1783 ;; FIXME: Backends that want to print the state in a different way
1784 ;; can do it by defining the `status-printer' function. Using
1785 ;; `prettify-state-info' adds two extra vc-calls per item, which
1786 ;; is too expensive.
1787 ;;(prettified (if isdir state (vc-call-backend backend 'prettify-state-info filename))))
1788 (insert
1789 (propertize
1790 (format "%c" (if (vc-dir-fileinfo->marked fileentry) ?* ? ))
1791 'face 'font-lock-type-face)
1792 " "
1793 (propertize
1794 (format "%-20s" state)
1795 'face (cond ((eq state 'up-to-date) 'font-lock-builtin-face)
1796 ((memq state '(missing conflict)) 'font-lock-warning-face)
1797 (t 'font-lock-variable-name-face))
1798 'mouse-face 'highlight)
1799 " "
1800 (propertize
1801 (format "%s" filename)
1802 'face 'font-lock-function-name-face
1803 'mouse-face 'highlight))))
1804
1805 (defun vc-default-extra-status-menu (backend)
1806 nil)
1807
1808 (defun vc-dir-refresh-files (files default-state)
1809 "Refresh some files in the *VC-dir* buffer."
1810 (let ((def-dir default-directory)
1811 (backend vc-dir-backend))
1812 (vc-set-mode-line-busy-indicator)
1813 ;; Call the `dir-status-file' backend function.
1814 ;; `dir-status-file' is supposed to be asynchronous.
1815 ;; It should compute the results, and then call the function
1816 ;; passed as an argument in order to update the vc-dir buffer
1817 ;; with the results.
1818 (unless (buffer-live-p vc-dir-process-buffer)
1819 (setq vc-dir-process-buffer
1820 (generate-new-buffer (format " *VC-%s* tmp status" backend))))
1821 (lexical-let ((buffer (current-buffer)))
1822 (with-current-buffer vc-dir-process-buffer
1823 (cd def-dir)
1824 (erase-buffer)
1825 (vc-call-backend
1826 backend 'dir-status-files def-dir files default-state
1827 (lambda (entries &optional more-to-come)
1828 ;; ENTRIES is a list of (FILE VC_STATE EXTRA) items.
1829 ;; If MORE-TO-COME is true, then more updates will come from
1830 ;; the asynchronous process.
1831 (with-current-buffer buffer
1832 (vc-dir-update entries buffer)
1833 (unless more-to-come
1834 (setq mode-line-process nil)
1835 ;; Remove the ones that haven't been updated at all.
1836 ;; Those not-updated are those whose state is nil because the
1837 ;; file/dir doesn't exist and isn't versioned.
1838 (ewoc-filter vc-ewoc
1839 (lambda (info)
1840 ;; The state for directory entries might
1841 ;; have been changed to 'up-to-date,
1842 ;; reset it, othewise it will be removed when doing 'x'
1843 ;; next time.
1844 ;; FIXME: There should be a more elegant way to do this.
1845 (when (and (vc-dir-fileinfo->directory info)
1846 (eq (vc-dir-fileinfo->state info)
1847 'up-to-date))
1848 (setf (vc-dir-fileinfo->state info) nil))
1849
1850 (not (vc-dir-fileinfo->needs-update info))))))))))))
1851
1852 (defun vc-dir-refresh ()
1853 "Refresh the contents of the *VC-dir* buffer.
1854 Throw an error if another update process is in progress."
1855 (interactive)
1856 (if (vc-dir-busy)
1857 (error "Another update process is in progress, cannot run two at a time")
1858 (let ((def-dir default-directory)
1859 (backend vc-dir-backend))
1860 (vc-set-mode-line-busy-indicator)
1861 ;; Call the `dir-status' backend function.
1862 ;; `dir-status' is supposed to be asynchronous.
1863 ;; It should compute the results, and then call the function
1864 ;; passed as an argument in order to update the vc-dir buffer
1865 ;; with the results.
1866
1867 ;; Create a buffer that can be used by `dir-status' and call
1868 ;; `dir-status' with this buffer as the current buffer. Use
1869 ;; `vc-dir-process-buffer' to remember this buffer, so that
1870 ;; it can be used later to kill the update process in case it
1871 ;; takes too long.
1872 (unless (buffer-live-p vc-dir-process-buffer)
1873 (setq vc-dir-process-buffer
1874 (generate-new-buffer (format " *VC-%s* tmp status" backend))))
1875 ;; set the needs-update flag on all entries
1876 (ewoc-map (lambda (info) (setf (vc-dir-fileinfo->needs-update info) t) nil)
1877 vc-ewoc)
1878 (lexical-let ((buffer (current-buffer)))
1879 (with-current-buffer vc-dir-process-buffer
1880 (cd def-dir)
1881 (erase-buffer)
1882 (vc-call-backend
1883 backend 'dir-status def-dir
1884 (lambda (entries &optional more-to-come)
1885 ;; ENTRIES is a list of (FILE VC_STATE EXTRA) items.
1886 ;; If MORE-TO-COME is true, then more updates will come from
1887 ;; the asynchronous process.
1888 (with-current-buffer buffer
1889 (vc-dir-update entries buffer)
1890 (unless more-to-come
1891 (let ((remaining
1892 (ewoc-collect
1893 vc-ewoc 'vc-dir-fileinfo->needs-update)))
1894 (if remaining
1895 (vc-dir-refresh-files
1896 (mapcar 'vc-dir-fileinfo->name remaining)
1897 'up-to-date)
1898 (setq mode-line-process nil))))))))))))
1899
1900 (defun vc-dir-show-fileentry (file)
1901 "Insert an entry for a specific file into the current *VC-dir* listing.
1902 This is typically used if the file is up-to-date (or has been added
1903 outside of VC) and one wants to do some operation on it."
1904 (interactive "fShow file: ")
1905 (vc-dir-update (list (list (file-relative-name file) (vc-state file))) (current-buffer)))
1906
1907 (defun vc-dir-hide-up-to-date ()
1908 "Hide up-to-date items from display."
1909 (interactive)
1910 (ewoc-filter
1911 vc-ewoc
1912 (lambda (crt) (not (eq (vc-dir-fileinfo->state crt) 'up-to-date)))))
1913
1914 (defun vc-default-status-fileinfo-extra (backend file)
1915 "Default absence of extra information returned for a file."
1916 nil)
1917
1918 ;; FIXME: Replace these with a more efficient dispatch
1919
1920 (defun vc-generic-status-printer (fileentry)
1921 (vc-call-backend vc-dir-backend 'status-printer fileentry))
1922
1923 (defun vc-generic-state (file)
1924 (vc-call-backend vc-dir-backend 'state file))
1925
1926 (defun vc-generic-status-fileinfo-extra (file)
1927 (vc-call-backend vc-dir-backend 'status-fileinfo-extra file))
1928
1929 (defun vc-dir-extra-menu ()
1930 (vc-call-backend vc-dir-backend 'extra-status-menu))
1931
1932 (defun vc-make-backend-object (file-or-dir)
1933 "Create the backend capability object needed by vc-dispatcher."
1934 (vc-create-client-object
1935 "VC dir"
1936 (vc-dir-headers vc-dir-backend file-or-dir)
1937 #'vc-generic-status-printer
1938 #'vc-generic-state
1939 #'vc-generic-status-fileinfo-extra
1940 #'vc-dir-refresh
1941 #'vc-dir-extra-menu))
1942
1943 ;;;###autoload
1944 (defun vc-dir (dir)
1945 "Show the VC status for DIR."
1946 (interactive "DVC status for directory: ")
1947 (pop-to-buffer (vc-dir-prepare-status-buffer "*vc-dir*" dir))
1948 (if (and (derived-mode-p 'vc-dir-mode) (boundp 'client-object))
1949 (vc-dir-refresh)
1950 ;; Otherwise, initialize a new view using the dispatcher layer
1951 (progn
1952 (set (make-local-variable 'vc-dir-backend) (vc-responsible-backend dir))
1953 ;; Build a capability object and hand it to the dispatcher initializer
1954 (vc-dir-mode (vc-make-backend-object dir))
1955 ;; FIXME: Make a derived-mode instead.
1956 ;; Add VC-specific keybindings
1957 (let ((map (current-local-map)))
1958 (define-key map "v" 'vc-next-action) ;; C-x v v
1959 (define-key map "=" 'vc-diff) ;; C-x v =
1960 (define-key map "i" 'vc-register) ;; C-x v i
1961 (define-key map "+" 'vc-update) ;; C-x v +
1962 (define-key map "l" 'vc-print-log) ;; C-x v l
1963 ;; More confusing than helpful, probably
1964 ;(define-key map "R" 'vc-revert) ;; u is taken by dispatcher unmark.
1965 ;(define-key map "A" 'vc-annotate) ;; g is taken by dispatcher refresh
1966 (define-key map "x" 'vc-dir-hide-up-to-date))
1967 )
1968 ;; FIXME: Needs to alter a buffer-local map, otherwise clients may clash
1969 (let ((map vc-dir-menu-map))
1970 ;; VC info details
1971 (define-key map [sepvcdet] '("--"))
1972 (define-key map [remup]
1973 '(menu-item "Hide up-to-date" vc-dir-hide-up-to-date
1974 :help "Hide up-to-date items from display"))
1975 ;; FIXME: This needs a key binding. And maybe a better name
1976 ;; ("Insert" like PCL-CVS uses does not sound that great either)...
1977 (define-key map [ins]
1978 '(menu-item "Show File" vc-dir-show-fileentry
1979 :help "Show a file in the VC status listing even though it might be up to date"))
1980 (define-key map [annotate]
1981 '(menu-item "Annotate" vc-annotate
1982 :help "Display the edit history of the current file using colors"))
1983 (define-key map [diff]
1984 '(menu-item "Compare with Base Version" vc-diff
1985 :help "Compare file set with the base version"))
1986 (define-key map [log]
1987 '(menu-item "Show history" vc-print-log
1988 :help "List the change log of the current file set in a window"))
1989 ;; VC commands.
1990 (define-key map [sepvccmd] '("--"))
1991 (define-key map [update]
1992 '(menu-item "Update to latest version" vc-update
1993 :help "Update the current fileset's files to their tip revisions"))
1994 (define-key map [revert]
1995 '(menu-item "Revert to base version" vc-revert
1996 :help "Revert working copies of the selected fileset to their repository contents."))
1997 (define-key map [next-action]
1998 ;; FIXME: This really really really needs a better name!
1999 ;; And a key binding too.
2000 '(menu-item "Check In/Out" vc-next-action
2001 :help "Do the next logical version control operation on the current fileset"))
2002 (define-key map [register]
2003 '(menu-item "Register" vc-dir-register
2004 :help "Register file set into the version control system"))
2005 )))
2006
2007 ;; Named-configuration entry points 1766 ;; Named-configuration entry points
2008 1767
2009 (defun vc-tag-precondition (dir) 1768 (defun vc-tag-precondition (dir)
2010 "Scan the tree below DIR, looking for files not up-to-date. 1769 "Scan the tree below DIR, looking for files not up-to-date.
2011 If any file is not up-to-date, return the name of the first such file. 1770 If any file is not up-to-date, return the name of the first such file.