Mercurial > emacs
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. |