annotate lisp/dired/dired-link.el @ 5:49b78a777eb4

Added tag r19-15b3 for changeset b82b59fe008d
author cvs
date Mon, 13 Aug 2007 08:46:57 +0200
parents 376386a54a3c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1 ;;!emacs
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
2 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
3 ;; FILE: dired-link.el
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
4 ;; SUMMARY: Properly resolves UNIX (and Apollo variant) links under dired.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
5 ;; Works for both classic dired (V18) and tree dired (V19).
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
6 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
7 ;; AUTHOR: Bob Weiner
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
8 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
9 ;; ORIG-DATE: 09-May-89
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
10 ;; LAST-MOD: 30-Aug-92 at 19:15:57 by Bob Weiner
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
11 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
12 ;; Copyright (C) 1989, 1991, 1992, Free Software Foundation, Inc.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
13 ;; Available for use and distribution under the same terms as GNU Emacs.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
14 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
15 ;; This file is part of InfoDock.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
16 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
17 ;; DESCRIPTION:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
18 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
19 ;; This library is used in conjunction with the Emacs dired facility.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
20 ;; To install it, simply load this file or create a
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
21 ;; dired hook which loads this file. Then use {M-x dired <directory> RTN}
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
22 ;; or {C-x C-f <directory> RTN} as one normally would.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
23 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
24 ;; The changes below to 'dired-noselect' assume UNIX shell file
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
25 ;; abbreviation and UNIX file name conventions.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
26 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
27 ;; This modified version of the 'dired-noselect' function automatically
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
28 ;; resolves all recursive links properly and edits the final directory that
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
29 ;; a link points to, called the link referent. It handles Apollo-isms such
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
30 ;; as /usr/local -> $(SERVER_LOCAL)/usr/local, /usr/bin ->
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
31 ;; ../$(SYSTYPE)/usr/bin and /tmp -> `node_data/tmp. It also handles
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
32 ;; relative links properly as in /usr/local/emacs -> gnu/emacs which must
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
33 ;; be resolved relative to the '/usr/local' directory.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
34 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
35 ;; DESCRIP-END.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
36
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
37 ;; ************************************************************************
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
38 ;; Internal functions
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
39 ;; ************************************************************************
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
40
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
41 ;; Normally, if one performs a dired multiple times on a directory which is a
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
42 ;; link, a new buffer will be created each time. This is due to the fact
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
43 ;; that 'dired-find-buffer' is called in 'dired-noselect' before the link is
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
44 ;; resolved. The following code solves this problem by checking for a
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
45 ;; previously existing buffer that is performing dired on the directory that
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
46 ;; the link resolves to. This is also done recursively. If one is found,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
47 ;; the dired buffer that shows the link is killed and the previously existing
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
48 ;; one is used and re-read in.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
49
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
50 (defun dired-link-noselect-classic (dirname)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
51 "Like M-x dired but returns the dired buffer as value, does not select it."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
52 (or dirname (setq dirname default-directory))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
53 (setq dirname (dired-link-referent (directory-file-name dirname)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
54 (if (equal dirname "")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
55 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
56 (if (= (aref dirname 0) ?~) (setq dirname (expand-file-name dirname)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
57 (if (file-directory-p dirname)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
58 (setq dirname (file-name-as-directory dirname)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
59 (let ((buffer (dired-find-buffer dirname)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
60 (set-buffer buffer)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
61 (dired-readin dirname buffer)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
62 (dired-move-to-filename)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
63 (dired-mode dirname)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
64 buffer)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
65
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
66 (defun dired-link-noselect-tree (dirname &optional switches)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
67 "Like `dired' but returns the dired buffer as value, does not select it."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
68 (or dirname (setq dirname default-directory))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
69 (setq dirname (expand-file-name
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
70 (dired-link-referent (directory-file-name dirname))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
71 (if (file-directory-p dirname)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
72 (setq dirname (file-name-as-directory dirname)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
73 (dired-internal-noselect dirname switches))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
74
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
75 ;; Overload as appropriate for Classic (V18) or Tree Dired
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
76 (fset 'dired-noselect (if (fboundp 'dired-internal-noselect)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
77 'dired-link-noselect-tree
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
78 'dired-link-noselect-classic))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
79
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
80 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
81 ;; Resolves all UNIX links.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
82 ;; Works with Apollo's variant and other strange links. Will fail on
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
83 ;; Apollos if the '../' notation is used to move just above the '/'
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
84 ;; directory level. This is fairly uncommon and so the problem has not been
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
85 ;; fixed.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
86 ;;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
87 (defun dired-link-referent (linkname)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
88 "Returns expanded file or directory referent of LINKNAME.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
89 LINKNAME should not end with a directory delimiter.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
90 If LINKNAME is not a string, returns nil.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
91 If LINKNAME is not a link, it is simply expanded and returned."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
92 (if (not (stringp linkname))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
93 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
94 (let ((referent))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
95 (while (setq referent (file-symlink-p linkname))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
96 (setq linkname (dired-link-expand
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
97 referent (file-name-directory linkname)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
98 (dired-link-expand linkname (file-name-directory linkname))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
99
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
100 (defun dired-link-expand (referent dirname)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
101 "Expands REFERENT relative to DIRNAME and returns."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
102 (let ((var-link)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
103 (dir dirname))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
104 (while (string-match "\\$(\\([^\)]*\\))" referent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
105 (setq var-link (getenv (substring referent (match-beginning 1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
106 (match-end 1)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
107 referent (concat (substring referent 0 (match-beginning 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
108 var-link
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
109 (substring referent (match-end 0)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
110 ;; If referent is not an absolute path
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
111 (let ((nd-abbrev (string-match "`node_data" referent)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
112 (if (and nd-abbrev (= nd-abbrev 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
113 (setq referent (concat
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
114 ;; Prepend node name given in dirname, if any
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
115 (and (string-match "^//[^/]+" dirname)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
116 (substring dirname 0 (match-end 0)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
117 "/sys/" (substring referent 1)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
118 (while (string-match "\\.\\." referent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
119 ;; Match to "//.." or "/.." at the start of link referent
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
120 (while (string-match "^\\(//\\.\\.\\|/\\.\\.\\)\\(/\\|$\\)" referent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
121 (setq referent (substring referent (match-end 1))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
122 ;; Match to "../" or ".." at the start of link referent
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
123 (while (string-match "^\\.\\.\\(/\\|$\\)" referent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
124 (setq dir (file-name-directory (directory-file-name dir))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
125 referent (concat dir (substring referent (match-end 0)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
126 ;; Match to rest of "../" in link referent
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
127 (while (string-match "[^/]+/\\.\\./" referent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
128 (setq referent (concat (substring referent 0 (match-beginning 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
129 (substring referent (match-end 0))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
130 (and (/= (aref referent 0) ?~)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
131 (/= (aref referent 0) ?/)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
132 (setq referent (concat dirname referent))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
133 referent)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
134
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
135 (provide 'dired-link)