uniquify.el 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. ;;; uniquify.el --- unique buffer names dependent on file name -*- lexical-binding: t -*-
  2. ;; Copyright (C) 1989, 1995-1997, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: Dick King <king@reasoning.com>
  4. ;; Maintainer: FSF
  5. ;; Keywords: files
  6. ;; Created: 15 May 86
  7. ;; Package: emacs
  8. ;; This file is part of GNU Emacs.
  9. ;; GNU Emacs is free software: you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; GNU Emacs is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Commentary:
  20. ;; Emacs's standard method for making buffer names unique adds <2>, <3>,
  21. ;; etc. to the end of (all but one of) the buffers. This file replaces
  22. ;; that behavior, for buffers visiting files and dired buffers, with a
  23. ;; uniquification that adds parts of the file name until the buffer names
  24. ;; are unique. For instance, buffers visiting /u/mernst/tmp/Makefile and
  25. ;; /usr/projects/zaphod/Makefile would be named Makefile|tmp and
  26. ;; Makefile|zaphod, respectively (instead of Makefile and Makefile<2>).
  27. ;; Other buffer name styles are also available.
  28. ;; To use this file, do (require 'uniquify)
  29. ;; and set uniquify-buffer-name-style to one of its non-nil alternative values.
  30. ;; For other options, see "User-visible variables", below.
  31. ;; A version of uniquify.el that works under Emacs 18, Emacs 19, XEmacs,
  32. ;; and InfoDock is available from the maintainer.
  33. ;;; Change Log:
  34. ;; Originally by Dick King <king@reasoning.com> 15 May 86
  35. ;; Converted for Emacs 18 by Stephen Gildea <gildea@stop.mail-abuse.org>
  36. ;; Make uniquify-min-dir-content 0 truly non-invasive. gildea 23 May 89
  37. ;; Some cleanup. uniquify-min-dir-content default 0. gildea 01 Jun 89
  38. ;; Don't rename to "". Michael Ernst <mernst@theory.lcs.mit.edu> 15 Jun 94
  39. ;; Add kill-buffer-hook. Kenneth Manheimer <ken.manheimer@nist.gov> 09 May 95
  40. ;; Add advice for rename-buffer and create-file-buffer, handle dired buffers,
  41. ;; kill-buffer-rationalize-buffer-names-p, documentation. mernst 24 May 95
  42. ;; Remove free variables, fix typos. mernst 5 Jun 95
  43. ;; Efficiently support Emacs 19.27 & earlier. ken.manheimer, mernst 10 Jun 95
  44. ;; Rename user options to "uniquify-...", add uniquify-reverse-dir-content-p,
  45. ;; add uniquify-ask-about-buffer-names-p. king, mernst 13 Jun 95
  46. ;; Prefix functions by "uniquify-..."; rename mnemonic-buffer-names to
  47. ;; uniquify-buffer-name-style; add 'forward and 'post-forward-angle-brackets
  48. ;; styles; remove uniquify-reverse-dir-content-p; add
  49. ;; uniquify-trailing-separator-p. mernst 4 Aug 95
  50. ;; Don't call expand-file-name on nil. mernst 7 Jan 96
  51. ;; Check whether list-buffers-directory is bound. mernst 11 Oct 96
  52. ;; Ignore non-file non-dired buffers. Colin Rafferty <craffert@ml.com> 3 Mar 97
  53. ;; Use last component, not "", for file name of directories. mernst 27 Jun 97
  54. ;; Use directory-file-name; code cleanup. mernst 6 Sep 97
  55. ;; Add uniquify-ignore-buffers-re.
  56. ;; Andre Srinivasan <andre@visigenic.com> 9 Sep 97
  57. ;; Add uniquify-list-buffers-directory-modes
  58. ;; Stefan Monnier <monnier@cs.yale.edu> 17 Nov 2000
  59. ;; Algorithm and data structure changed to reduce consing with lots of buffers
  60. ;; Francesco Potortì <pot@gnu.org> (ideas by rms and monnier) 2001-07-18
  61. ;; Valuable feedback was provided by
  62. ;; Paul Smith <psmith@baynetworks.com>,
  63. ;; Alastair Burt <burt@dfki.uni-kl.de>,
  64. ;; Bob Weiner <weiner@footloose.sps.mot.com>,
  65. ;; Albert L. Ting <alt@vlibs.com>,
  66. ;; gyro@reasoning.com,
  67. ;; Bryan O'Sullivan <bos@eng.sun.com>.
  68. ;;; Code:
  69. (eval-when-compile (require 'cl))
  70. ;;; User-visible variables
  71. (defgroup uniquify nil
  72. "Unique buffer names dependent on file name."
  73. :group 'files)
  74. (defcustom uniquify-buffer-name-style nil
  75. "If non-nil, buffer names are uniquified with parts of directory name.
  76. The value determines the buffer name style and is one of `forward',
  77. `reverse', `post-forward', or `post-forward-angle-brackets'.
  78. For example, files `/foo/bar/mumble/name' and `/baz/quux/mumble/name'
  79. would have the following buffer names in the various styles:
  80. forward bar/mumble/name quux/mumble/name
  81. reverse name\\mumble\\bar name\\mumble\\quux
  82. post-forward name|bar/mumble name|quux/mumble
  83. post-forward-angle-brackets name<bar/mumble> name<quux/mumble>
  84. nil name name<2>
  85. Of course, the \"mumble\" part may be stripped as well, depending on the setting
  86. of `uniquify-strip-common-suffix'."
  87. :type '(radio (const forward)
  88. (const reverse)
  89. (const post-forward)
  90. (const post-forward-angle-brackets)
  91. (const :tag "standard Emacs behavior (nil)" nil))
  92. :require 'uniquify
  93. :group 'uniquify)
  94. (defcustom uniquify-after-kill-buffer-p t
  95. "If non-nil, rerationalize buffer names after a buffer has been killed."
  96. :type 'boolean
  97. :group 'uniquify)
  98. (defcustom uniquify-ask-about-buffer-names-p nil
  99. "If non-nil, permit user to choose names for buffers with same base file.
  100. If the user chooses to name a buffer, uniquification is preempted and no
  101. other buffer names are changed."
  102. :type 'boolean
  103. :group 'uniquify)
  104. ;; The default value matches certain Gnus buffers.
  105. (defcustom uniquify-ignore-buffers-re nil
  106. "Regular expression matching buffer names that should not be uniquified.
  107. For instance, set this to \"^draft-[0-9]+$\" to avoid having uniquify rename
  108. draft buffers even if `uniquify-after-kill-buffer-p' is non-nil and the
  109. visited file name isn't the same as that of the buffer."
  110. :type '(choice (const :tag "Uniquify all buffers" nil) regexp)
  111. :group 'uniquify)
  112. (defcustom uniquify-min-dir-content 0
  113. "Minimum number of directory name components included in buffer name."
  114. :type 'integer
  115. :group 'uniquify)
  116. (defcustom uniquify-separator nil
  117. "String separator for buffer name components.
  118. When `uniquify-buffer-name-style' is `post-forward', separates
  119. base file name from directory part in buffer names (default \"|\").
  120. When `uniquify-buffer-name-style' is `reverse', separates all
  121. file name components (default \"\\\")."
  122. :type '(choice (const nil) string)
  123. :group 'uniquify)
  124. (defcustom uniquify-trailing-separator-p nil
  125. "If non-nil, add a file name separator to dired buffer names.
  126. If `uniquify-buffer-name-style' is `forward', add the separator at the end;
  127. if it is `reverse', add the separator at the beginning; otherwise, this
  128. variable is ignored."
  129. :type 'boolean
  130. :group 'uniquify)
  131. (defcustom uniquify-strip-common-suffix
  132. ;; Using it when uniquify-min-dir-content>0 doesn't make much sense.
  133. (eq 0 uniquify-min-dir-content)
  134. "If non-nil, strip common directory suffixes of conflicting files.
  135. E.g. if you open /a1/b/c/d and /a2/b/c/d, the buffer names will say
  136. \"d|a1\" and \"d|a2\" instead of \"d|a1/b/c\" and \"d|a2/b/c\".
  137. This can be handy when you have deep parallel hierarchies."
  138. :type 'boolean
  139. :group 'uniquify)
  140. (defvar uniquify-list-buffers-directory-modes '(dired-mode cvs-mode vc-dir-mode)
  141. "List of modes for which uniquify should obey `list-buffers-directory'.
  142. That means that when `buffer-file-name' is set to nil, `list-buffers-directory'
  143. contains the name of the directory which the buffer is visiting.")
  144. ;;; Utilities
  145. ;; uniquify-fix-list data structure
  146. (defstruct (uniquify-item
  147. (:constructor nil) (:copier nil)
  148. (:constructor uniquify-make-item
  149. (base dirname buffer &optional proposed)))
  150. base dirname buffer proposed)
  151. ;; Internal variables used free
  152. (defvar uniquify-possibly-resolvable nil)
  153. (defvar uniquify-managed nil
  154. "Non-nil if the name of this buffer is managed by uniquify.
  155. It actually holds the list of `uniquify-item's corresponding to the conflict.")
  156. (make-variable-buffer-local 'uniquify-managed)
  157. (put 'uniquify-managed 'permanent-local t)
  158. ;; Used in desktop.el to save the non-uniquified buffer name
  159. (defun uniquify-buffer-base-name ()
  160. "Return the base name of the current buffer.
  161. Return nil if the buffer is not managed by uniquify."
  162. (and uniquify-managed
  163. (uniquify-item-base (car uniquify-managed))))
  164. ;;; Main entry point.
  165. (defun uniquify-rationalize-file-buffer-names (base dirname newbuf)
  166. "Make file buffer names unique by adding segments from file name.
  167. If `uniquify-min-dir-content' > 0, always pulls that many
  168. file name elements.
  169. Arguments BASE, DIRNAME, and NEWBUF specify the new buffer that causes
  170. this rationalization."
  171. (interactive
  172. (list (if uniquify-managed
  173. (uniquify-item-base (car uniquify-managed)) (buffer-name))
  174. (uniquify-buffer-file-name (current-buffer))
  175. (current-buffer)))
  176. ;; Make sure we don't get confused by outdated uniquify-managed info in
  177. ;; this buffer.
  178. (with-current-buffer newbuf (setq uniquify-managed nil))
  179. (when dirname
  180. (setq dirname (expand-file-name (directory-file-name dirname)))
  181. (let ((fix-list (list (uniquify-make-item base dirname newbuf)))
  182. items)
  183. (dolist (buffer (buffer-list))
  184. (when (and (not (and uniquify-ignore-buffers-re
  185. (string-match uniquify-ignore-buffers-re
  186. (buffer-name buffer))))
  187. ;; Only try to rename buffers we actually manage.
  188. (setq items (buffer-local-value 'uniquify-managed buffer))
  189. (equal base (uniquify-item-base (car items)))
  190. ;; Don't re-add stuff we already have. Actually this
  191. ;; whole `and' test should only match at most once.
  192. (not (memq (car items) fix-list)))
  193. (unless (cdr items)
  194. ;; If there was no conflict, the buffer-name is equal to the
  195. ;; base-name and we may have missed a rename-buffer because
  196. ;; of code like in set-visited-file-name:
  197. ;; (or (string= new-name (buffer-name)) (rename-buffer new-name t))
  198. ;; So we need to refresh the dirname of the uniquify-item.
  199. (setf (uniquify-item-dirname (car items))
  200. (uniquify-buffer-file-name
  201. (uniquify-item-buffer (car items))))
  202. ;; This shouldn't happen, but maybe there's no dirname any more.
  203. (unless (uniquify-item-dirname (car items))
  204. (with-current-buffer (uniquify-item-buffer (car items))
  205. (setq uniquify-managed nil))
  206. (setq items nil)))
  207. ;; In case we missed some calls to kill-buffer, there may be dead
  208. ;; buffers in uniquify-managed, so filter them out.
  209. (setq items
  210. (delq nil (mapcar
  211. (lambda (item)
  212. (if (buffer-live-p (uniquify-item-buffer item))
  213. item))
  214. items)))
  215. (setq fix-list (append fix-list items))))
  216. ;; selects buffers whose names may need changing, and others that
  217. ;; may conflict, then bring conflicting names together
  218. (uniquify-rationalize fix-list))))
  219. ;; uniquify's version of buffer-file-name; result never contains trailing slash
  220. (defun uniquify-buffer-file-name (buffer)
  221. "Return name of directory, file BUFFER is visiting, or nil if none.
  222. Works on ordinary file-visiting buffers and buffers whose mode is mentioned
  223. in `uniquify-list-buffers-directory-modes', otherwise returns nil."
  224. (with-current-buffer buffer
  225. (let ((filename
  226. (or buffer-file-name
  227. (if (memq major-mode uniquify-list-buffers-directory-modes)
  228. list-buffers-directory))))
  229. (when filename
  230. (directory-file-name
  231. (file-name-directory
  232. (expand-file-name
  233. (directory-file-name filename))))))))
  234. (defun uniquify-rerationalize-w/o-cb (fix-list)
  235. "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."
  236. (let ((new-fix-list nil))
  237. (dolist (item fix-list)
  238. (let ((buf (uniquify-item-buffer item)))
  239. (unless (or (eq buf (current-buffer)) (not (buffer-live-p buf)))
  240. (push item new-fix-list))))
  241. (when new-fix-list
  242. (uniquify-rationalize new-fix-list))))
  243. (defun uniquify-rationalize (fix-list)
  244. ;; Set up uniquify to re-rationalize after killing/renaming
  245. ;; if there is a conflict.
  246. (dolist (item fix-list)
  247. (with-current-buffer (uniquify-item-buffer item)
  248. ;; Refresh the dirnames and proposed names.
  249. (setf (uniquify-item-proposed item)
  250. (uniquify-get-proposed-name (uniquify-item-base item)
  251. (uniquify-item-dirname item)))
  252. (setq uniquify-managed fix-list)))
  253. ;; Strip any shared last directory names of the dirname.
  254. (when (and (cdr fix-list) uniquify-strip-common-suffix)
  255. (let ((strip t))
  256. (while (let* ((base (file-name-nondirectory
  257. (uniquify-item-dirname (car fix-list))))
  258. (items fix-list))
  259. (when (> (length base) 0)
  260. (while (and strip items)
  261. (unless (equal base (file-name-nondirectory
  262. (uniquify-item-dirname (pop items))))
  263. (setq strip nil)))
  264. strip))
  265. ;; It's all the same => strip.
  266. (dolist (item (prog1 fix-list (setq fix-list nil)))
  267. ;; Create new items because the old ones are kept (with the true
  268. ;; `dirname') for later rerationalizing.
  269. (push (uniquify-make-item (uniquify-item-base item)
  270. (let ((f (file-name-directory
  271. (uniquify-item-dirname item))))
  272. (and f (directory-file-name f)))
  273. (uniquify-item-buffer item)
  274. (uniquify-item-proposed item))
  275. fix-list)))))
  276. ;; If uniquify-min-dir-content is 0, this will end up just
  277. ;; passing fix-list to uniquify-rationalize-conflicting-sublist.
  278. (uniquify-rationalize-a-list fix-list))
  279. (defun uniquify-item-greaterp (item1 item2)
  280. (string-lessp (uniquify-item-proposed item2)
  281. (uniquify-item-proposed item1)))
  282. (defun uniquify-rationalize-a-list (fix-list &optional depth)
  283. (unless depth (setq depth uniquify-min-dir-content))
  284. (let (conflicting-sublist ; all elements have the same proposed name
  285. (old-proposed "")
  286. proposed)
  287. ;; Divide fix-list into items with same proposed names and pass them
  288. ;; to uniquify-rationalize-conflicting-sublist.
  289. (dolist (item (sort (copy-sequence fix-list) 'uniquify-item-greaterp))
  290. (setq proposed (uniquify-item-proposed item))
  291. (unless (equal proposed old-proposed)
  292. (uniquify-rationalize-conflicting-sublist conflicting-sublist
  293. old-proposed depth)
  294. (setq conflicting-sublist nil))
  295. (push item conflicting-sublist)
  296. (setq old-proposed proposed))
  297. (uniquify-rationalize-conflicting-sublist conflicting-sublist
  298. old-proposed depth)))
  299. (defun uniquify-get-proposed-name (base dirname &optional depth)
  300. (unless depth (setq depth uniquify-min-dir-content))
  301. (assert (equal (directory-file-name dirname) dirname)) ;No trailing slash.
  302. ;; Distinguish directories by adding extra separator.
  303. (if (and uniquify-trailing-separator-p
  304. (file-directory-p (expand-file-name base dirname))
  305. (not (string-equal base "")))
  306. (cond ((eq uniquify-buffer-name-style 'forward)
  307. (setq base (file-name-as-directory base)))
  308. ;; (setq base (concat base "/")))
  309. ((eq uniquify-buffer-name-style 'reverse)
  310. (setq base (concat (or uniquify-separator "\\") base)))))
  311. (let ((extra-string nil)
  312. (n depth))
  313. (while (and (> n 0) dirname)
  314. (let ((file (file-name-nondirectory dirname)))
  315. (when (setq dirname (file-name-directory dirname))
  316. (setq dirname (directory-file-name dirname)))
  317. (setq n (1- n))
  318. (push (if (zerop (length file)) ;nil or "".
  319. (prog1 (or (file-remote-p dirname) "")
  320. (setq dirname nil)) ;Could be `dirname' iso "".
  321. file)
  322. extra-string)))
  323. (when (zerop n)
  324. (if (and dirname extra-string
  325. (equal dirname (file-name-directory dirname)))
  326. ;; We're just before the root. Let's add the leading / already.
  327. ;; With "/a/b"+"/c/d/b" this leads to "/a/b" and "d/b" but with
  328. ;; "/a/b"+"/c/a/b" this leads to "/a/b" and "a/b".
  329. (push "" extra-string))
  330. (setq uniquify-possibly-resolvable t))
  331. (cond
  332. ((null extra-string) base)
  333. ((string-equal base "") ;Happens for dired buffers on the root directory.
  334. (mapconcat 'identity extra-string "/"))
  335. ((eq uniquify-buffer-name-style 'reverse)
  336. (mapconcat 'identity
  337. (cons base (nreverse extra-string))
  338. (or uniquify-separator "\\")))
  339. ((eq uniquify-buffer-name-style 'forward)
  340. (mapconcat 'identity (nconc extra-string (list base))
  341. "/"))
  342. ((eq uniquify-buffer-name-style 'post-forward)
  343. (concat base (or uniquify-separator "|")
  344. (mapconcat 'identity extra-string "/")))
  345. ((eq uniquify-buffer-name-style 'post-forward-angle-brackets)
  346. (concat base "<" (mapconcat 'identity extra-string "/")
  347. ">"))
  348. (t (error "Bad value for uniquify-buffer-name-style: %s"
  349. uniquify-buffer-name-style)))))
  350. ;; Deal with conflicting-sublist, all of whose elements have identical
  351. ;; "base" components.
  352. (defun uniquify-rationalize-conflicting-sublist (conf-list old-name depth)
  353. (when conf-list
  354. (if (or (cdr conf-list)
  355. ;; Check that the proposed name doesn't conflict with some
  356. ;; existing buffer.
  357. (let ((buf (get-buffer old-name)))
  358. (and buf (not (eq buf (uniquify-item-buffer (car conf-list)))))))
  359. (when uniquify-possibly-resolvable
  360. (setq uniquify-possibly-resolvable nil
  361. depth (1+ depth))
  362. (dolist (item conf-list)
  363. (setf (uniquify-item-proposed item)
  364. (uniquify-get-proposed-name
  365. (uniquify-item-base item)
  366. (uniquify-item-dirname item)
  367. depth)))
  368. (uniquify-rationalize-a-list conf-list depth))
  369. (unless (string= old-name "")
  370. (uniquify-rename-buffer (car conf-list) old-name)))))
  371. (defun uniquify-rename-buffer (item newname)
  372. (let ((buffer (uniquify-item-buffer item)))
  373. (unless (equal newname (buffer-name buffer))
  374. (with-current-buffer buffer
  375. (let ((uniquify-buffer-name-style nil)) ;Avoid hooks on rename-buffer.
  376. ;; Pass the `unique' arg, so the advice doesn't mark it as unmanaged.
  377. (rename-buffer newname t))))))
  378. ;;; Hooks from the rest of Emacs
  379. (defun uniquify-maybe-rerationalize-w/o-cb ()
  380. "Re-rationalize buffer names, ignoring current buffer."
  381. (and (cdr uniquify-managed)
  382. uniquify-buffer-name-style
  383. (uniquify-rerationalize-w/o-cb uniquify-managed)))
  384. ;; Buffer deletion
  385. ;; Rerationalize after a buffer is killed, to reduce coinciding buffer names.
  386. ;; This mechanism uses `kill-buffer-hook', which runs *before* deletion, so
  387. ;; it calls `uniquify-rerationalize-w/o-cb' to rerationalize the buffer list
  388. ;; ignoring the current buffer (which is going to be deleted anyway).
  389. (defun uniquify-kill-buffer-function ()
  390. "Re-rationalize buffer names, ignoring current buffer.
  391. For use on `kill-buffer-hook'."
  392. (and uniquify-after-kill-buffer-p
  393. (uniquify-maybe-rerationalize-w/o-cb)))
  394. ;; Ideally we'd like to add it buffer-locally, but that doesn't work
  395. ;; because kill-buffer-hook is not permanent-local :-(
  396. ;; FIXME kill-buffer-hook _is_ permanent-local in 22+.
  397. (add-hook 'kill-buffer-hook 'uniquify-kill-buffer-function)
  398. ;; The logical place to put all this code is in generate-new-buffer-name.
  399. ;; It's written in C, so we would add a generate-new-buffer-name-function
  400. ;; which, if non-nil, would be called instead of the C. One problem with
  401. ;; that is that generate-new-buffer-name takes a potential buffer name as
  402. ;; its argument -- not other information, such as what file the buffer will
  403. ;; visit.
  404. ;; The below solution works because generate-new-buffer-name is called
  405. ;; only by rename-buffer (which, as of 19.29, is never called from C) and
  406. ;; generate-new-buffer, which is called only by Lisp functions
  407. ;; create-file-buffer and rename-uniquely. Rename-uniquely generally
  408. ;; isn't used for buffers visiting files, so it's sufficient to hook
  409. ;; rename-buffer and create-file-buffer. (Setting find-file-hook isn't
  410. ;; sufficient.)
  411. (defadvice rename-buffer (after rename-buffer-uniquify activate)
  412. "Uniquify buffer names with parts of directory name."
  413. (uniquify-maybe-rerationalize-w/o-cb)
  414. (if (null (ad-get-arg 1)) ; no UNIQUE argument.
  415. ;; Mark this buffer so it won't be renamed by uniquify.
  416. (setq uniquify-managed nil)
  417. (when uniquify-buffer-name-style
  418. ;; Rerationalize w.r.t the new name.
  419. (uniquify-rationalize-file-buffer-names
  420. (ad-get-arg 0)
  421. (uniquify-buffer-file-name (current-buffer))
  422. (current-buffer))
  423. (setq ad-return-value (buffer-name (current-buffer))))))
  424. (defadvice create-file-buffer (after create-file-buffer-uniquify activate)
  425. "Uniquify buffer names with parts of directory name."
  426. (if uniquify-buffer-name-style
  427. (let ((filename (expand-file-name (directory-file-name (ad-get-arg 0)))))
  428. (uniquify-rationalize-file-buffer-names
  429. (file-name-nondirectory filename)
  430. (file-name-directory filename) ad-return-value))))
  431. ;;; The End
  432. (defun uniquify-unload-function ()
  433. "Unload the uniquify library."
  434. (save-current-buffer
  435. (let ((buffers nil))
  436. (dolist (buf (buffer-list))
  437. (set-buffer buf)
  438. (when uniquify-managed
  439. (push (cons buf (uniquify-item-base (car uniquify-managed))) buffers)))
  440. (dolist (fun '(rename-buffer create-file-buffer))
  441. (ad-remove-advice fun 'after (intern (concat (symbol-name fun) "-uniquify")))
  442. (ad-update fun))
  443. (dolist (buf buffers)
  444. (set-buffer (car buf))
  445. (rename-buffer (cdr buf) t))))
  446. ;; continue standard unloading
  447. nil)
  448. (provide 'uniquify)
  449. ;;; uniquify.el ends here