diff options
| -rw-r--r-- | lisp/files.el | 109 | ||||
| -rw-r--r-- | lisp/progmodes/flymake.el | 5 | ||||
| -rw-r--r-- | lisp/vc-hooks.el | 38 |
3 files changed, 89 insertions, 63 deletions
diff --git a/lisp/files.el b/lisp/files.el index 1fd6265e949..710c2a4f367 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -716,33 +716,84 @@ PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)." | |||
| 716 | string nil action)) | 716 | string nil action)) |
| 717 | (make-obsolete 'locate-file-completion 'locate-file-completion-table "23.1") | 717 | (make-obsolete 'locate-file-completion 'locate-file-completion-table "23.1") |
| 718 | 718 | ||
| 719 | (defun locate-dominating-file (file regexp) | 719 | (defvar locate-dominating-stop-dir-regexp |
| 720 | "Look up the directory hierarchy from FILE for a file matching REGEXP." | 720 | "\\`\\(?:[\\/][\\/]\\|/\\(?:net\\|afs\\|\\.\\\.\\.\\)/\\)\\'" |
| 721 | (catch 'found | 721 | "Regexp of directory names which stop the search in `locate-dominating-file'. |
| 722 | ;; `user' is not initialized yet because `file' may not exist, so we may | 722 | Any directory whose name matches this regexp will be treated like |
| 723 | ;; have to walk up part of the hierarchy before we find the "initial UID". | 723 | a kind of root directory by `locate-dominating-file' which will stop its search |
| 724 | (let ((user nil) | 724 | when it bumps into it. |
| 725 | ;; Abbreviate, so as to stop when we cross ~/. | 725 | The default regexp prevents fruitless and time-consuming attempts to find |
| 726 | (dir (abbreviate-file-name (file-name-as-directory file))) | 726 | special files in directories in which filenames are interpreted as hostnames.") |
| 727 | files) | 727 | |
| 728 | (while (and dir | 728 | ;; (defun locate-dominating-files (file regexp) |
| 729 | ;; As a heuristic, we stop looking up the hierarchy of | 729 | ;; "Look up the directory hierarchy from FILE for a file matching REGEXP. |
| 730 | ;; directories as soon as we find a directory belonging to | 730 | ;; Stop at the first parent where a matching file is found and return the list |
| 731 | ;; another user. This should save us from looking in | 731 | ;; of files that that match in this directory." |
| 732 | ;; things like /net and /afs. This assumes that all the | 732 | ;; (catch 'found |
| 733 | ;; files inside a project belong to the same user. | 733 | ;; ;; `user' is not initialized yet because `file' may not exist, so we may |
| 734 | (let ((prev-user user)) | 734 | ;; ;; have to walk up part of the hierarchy before we find the "initial UID". |
| 735 | (setq user (nth 2 (file-attributes dir))) | 735 | ;; (let ((user nil) |
| 736 | (or (null prev-user) (equal user prev-user)))) | 736 | ;; ;; Abbreviate, so as to stop when we cross ~/. |
| 737 | (if (setq files (condition-case nil | 737 | ;; (dir (abbreviate-file-name (file-name-as-directory file))) |
| 738 | (directory-files dir 'full regexp) | 738 | ;; files) |
| 739 | (error nil))) | 739 | ;; (while (and dir |
| 740 | (throw 'found (car files)) | 740 | ;; ;; As a heuristic, we stop looking up the hierarchy of |
| 741 | (if (equal dir | 741 | ;; ;; directories as soon as we find a directory belonging to |
| 742 | (setq dir (file-name-directory | 742 | ;; ;; another user. This should save us from looking in |
| 743 | (directory-file-name dir)))) | 743 | ;; ;; things like /net and /afs. This assumes that all the |
| 744 | (setq dir nil)))) | 744 | ;; ;; files inside a project belong to the same user. |
| 745 | nil))) | 745 | ;; (let ((prev-user user)) |
| 746 | ;; (setq user (nth 2 (file-attributes dir))) | ||
| 747 | ;; (or (null prev-user) (equal user prev-user)))) | ||
| 748 | ;; (if (setq files (condition-case nil | ||
| 749 | ;; (directory-files dir 'full regexp 'nosort) | ||
| 750 | ;; (error nil))) | ||
| 751 | ;; (throw 'found files) | ||
| 752 | ;; (if (equal dir | ||
| 753 | ;; (setq dir (file-name-directory | ||
| 754 | ;; (directory-file-name dir)))) | ||
| 755 | ;; (setq dir nil)))) | ||
| 756 | ;; nil))) | ||
| 757 | |||
| 758 | (defun locate-dominating-file (file name) | ||
| 759 | "Look up the directory hierarchy from FILE for a file named NAME. | ||
| 760 | Stop at the first parent directory containing a file NAME return the directory. | ||
| 761 | Return nil if not found." | ||
| 762 | ;; We used to use the above locate-dominating-files code, but the | ||
| 763 | ;; directory-files call is very costly, so we're much better off doing | ||
| 764 | ;; multiple calls using the code in here. | ||
| 765 | ;; | ||
| 766 | ;; Represent /home/luser/foo as ~/foo so that we don't try to look for | ||
| 767 | ;; `name' in /home or in /. | ||
| 768 | (setq file (abbreviate-file-name file)) | ||
| 769 | (let ((root nil) | ||
| 770 | (prev-file file) | ||
| 771 | ;; `user' is not initialized outside the loop because | ||
| 772 | ;; `file' may not exist, so we may have to walk up part of the | ||
| 773 | ;; hierarchy before we find the "initial UID". | ||
| 774 | (user nil) | ||
| 775 | try) | ||
| 776 | (while (not (or root | ||
| 777 | (null file) | ||
| 778 | ;; FIXME: Disabled this heuristic because it is sometimes | ||
| 779 | ;; inappropriate. | ||
| 780 | ;; As a heuristic, we stop looking up the hierarchy of | ||
| 781 | ;; directories as soon as we find a directory belonging | ||
| 782 | ;; to another user. This should save us from looking in | ||
| 783 | ;; things like /net and /afs. This assumes that all the | ||
| 784 | ;; files inside a project belong to the same user. | ||
| 785 | ;; (let ((prev-user user)) | ||
| 786 | ;; (setq user (nth 2 (file-attributes file))) | ||
| 787 | ;; (and prev-user (not (equal user prev-user)))) | ||
| 788 | (string-match locate-dominating-stop-dir-regexp file))) | ||
| 789 | (setq try (file-exists-p (expand-file-name name file))) | ||
| 790 | (cond (try (setq root file)) | ||
| 791 | ((equal file (setq prev-file file | ||
| 792 | file (file-name-directory | ||
| 793 | (directory-file-name file)))) | ||
| 794 | (setq file nil)))) | ||
| 795 | root)) | ||
| 796 | |||
| 746 | 797 | ||
| 747 | (defun executable-find (command) | 798 | (defun executable-find (command) |
| 748 | "Search for COMMAND in `exec-path' and return the absolute file name. | 799 | "Search for COMMAND in `exec-path' and return the absolute file name. |
| @@ -3159,10 +3210,10 @@ If the file is in a registered project, a cons from | |||
| 3159 | `project-directory-alist' is returned. | 3210 | `project-directory-alist' is returned. |
| 3160 | Otherwise this returns nil." | 3211 | Otherwise this returns nil." |
| 3161 | (setq file (expand-file-name file)) | 3212 | (setq file (expand-file-name file)) |
| 3162 | (let* ((settings (locate-dominating-file file "\\`\\.dir-settings\\.el\\'")) | 3213 | (let* ((settings (locate-dominating-file file ".dir-settings.el")) |
| 3163 | (pda nil)) | 3214 | (pda nil)) |
| 3164 | ;; `locate-dominating-file' may have abbreviated the name. | 3215 | ;; `locate-dominating-file' may have abbreviated the name. |
| 3165 | (if settings (setq settings (expand-file-name settings))) | 3216 | (if settings (setq settings (expand-file-name ".dir-settings.el" settings))) |
| 3166 | (dolist (x project-directory-alist) | 3217 | (dolist (x project-directory-alist) |
| 3167 | (when (and (eq t (compare-strings file nil (length (car x)) | 3218 | (when (and (eq t (compare-strings file nil (length (car x)) |
| 3168 | (car x) nil nil)) | 3219 | (car x) nil nil)) |
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 7f35e300994..b5856f3e115 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el | |||
| @@ -340,13 +340,10 @@ Return nil if we cannot, non-nil if we can." | |||
| 340 | Buildfile includes Makefile, build.xml etc. | 340 | Buildfile includes Makefile, build.xml etc. |
| 341 | Return its file name if found, or nil if not found." | 341 | Return its file name if found, or nil if not found." |
| 342 | (or (flymake-get-buildfile-from-cache source-dir-name) | 342 | (or (flymake-get-buildfile-from-cache source-dir-name) |
| 343 | (let* ((file (locate-dominating-file | 343 | (let* ((file (locate-dominating-file source-dir-name buildfile-name))) |
| 344 | source-dir-name | ||
| 345 | (concat "\\`" (regexp-quote buildfile-name) "\\'")))) | ||
| 346 | (if file | 344 | (if file |
| 347 | (progn | 345 | (progn |
| 348 | (flymake-log 3 "found buildfile at %s" file) | 346 | (flymake-log 3 "found buildfile at %s" file) |
| 349 | (setq file (file-name-directory file)) | ||
| 350 | (flymake-add-buildfile-to-cache source-dir-name file) | 347 | (flymake-add-buildfile-to-cache source-dir-name file) |
| 351 | file) | 348 | file) |
| 352 | (progn | 349 | (progn |
diff --git a/lisp/vc-hooks.el b/lisp/vc-hooks.el index 7910c068833..97dca35463d 100644 --- a/lisp/vc-hooks.el +++ b/lisp/vc-hooks.el | |||
| @@ -52,7 +52,7 @@ BACKEND, use `vc-handled-backends'." | |||
| 52 | 52 | ||
| 53 | (defcustom vc-ignore-dir-regexp | 53 | (defcustom vc-ignore-dir-regexp |
| 54 | ;; Stop SMB, automounter, AFS, and DFS host lookups. | 54 | ;; Stop SMB, automounter, AFS, and DFS host lookups. |
| 55 | "\\`\\(?:[\\/][\\/]\\|/\\(?:net\\|afs\\|\\.\\\.\\.\\)/\\)\\'" | 55 | locate-dominating-stop-dir-regexp |
| 56 | "Regexp matching directory names that are not under VC's control. | 56 | "Regexp matching directory names that are not under VC's control. |
| 57 | The default regexp prevents fruitless and time-consuming attempts | 57 | The default regexp prevents fruitless and time-consuming attempts |
| 58 | to determine the VC status in directories in which filenames are | 58 | to determine the VC status in directories in which filenames are |
| @@ -331,34 +331,11 @@ non-nil if FILE exists and its contents were successfully inserted." | |||
| 331 | "Find the root of a checked out project. | 331 | "Find the root of a checked out project. |
| 332 | The function walks up the directory tree from FILE looking for WITNESS. | 332 | The function walks up the directory tree from FILE looking for WITNESS. |
| 333 | If WITNESS if not found, return nil, otherwise return the root." | 333 | If WITNESS if not found, return nil, otherwise return the root." |
| 334 | ;; Represent /home/luser/foo as ~/foo so that we don't try to look for | 334 | (let ((locate-dominating-stop-dir-regexp |
| 335 | ;; witnesses in /home or in /. | 335 | (or vc-ignore-dir-regexp locate-dominating-stop-dir-regexp))) |
| 336 | (setq file (abbreviate-file-name file)) | 336 | (locate-dominating-file file witness))) |
| 337 | (let ((root nil) | 337 | |
| 338 | (prev-file file) | 338 | (define-obsolete-function-alias 'vc-find-root 'locate-dominating-file "23.1") |
| 339 | ;; `user' is not initialized outside the loop because | ||
| 340 | ;; `file' may not exist, so we may have to walk up part of the | ||
| 341 | ;; hierarchy before we find the "initial UID". | ||
| 342 | (user nil) | ||
| 343 | try) | ||
| 344 | (while (not (or root | ||
| 345 | (null file) | ||
| 346 | ;; As a heuristic, we stop looking up the hierarchy of | ||
| 347 | ;; directories as soon as we find a directory belonging | ||
| 348 | ;; to another user. This should save us from looking in | ||
| 349 | ;; things like /net and /afs. This assumes that all the | ||
| 350 | ;; files inside a project belong to the same user. | ||
| 351 | (let ((prev-user user)) | ||
| 352 | (setq user (nth 2 (file-attributes file))) | ||
| 353 | (and prev-user (not (equal user prev-user)))) | ||
| 354 | (string-match vc-ignore-dir-regexp file))) | ||
| 355 | (setq try (file-exists-p (expand-file-name witness file))) | ||
| 356 | (cond (try (setq root file)) | ||
| 357 | ((equal file (setq prev-file file | ||
| 358 | file (file-name-directory | ||
| 359 | (directory-file-name file)))) | ||
| 360 | (setq file nil)))) | ||
| 361 | root)) | ||
| 362 | 339 | ||
| 363 | ;; Access functions to file properties | 340 | ;; Access functions to file properties |
| 364 | ;; (Properties should be _set_ using vc-file-setprop, but | 341 | ;; (Properties should be _set_ using vc-file-setprop, but |
| @@ -378,7 +355,8 @@ file was previously registered under a certain backend, then that | |||
| 378 | backend is tried first." | 355 | backend is tried first." |
| 379 | (let (handler) | 356 | (let (handler) |
| 380 | (cond | 357 | (cond |
| 381 | ((and (file-name-directory file) (string-match vc-ignore-dir-regexp (file-name-directory file))) | 358 | ((and (file-name-directory file) |
| 359 | (string-match vc-ignore-dir-regexp (file-name-directory file))) | ||
| 382 | nil) | 360 | nil) |
| 383 | ((and (boundp 'file-name-handler-alist) | 361 | ((and (boundp 'file-name-handler-alist) |
| 384 | (setq handler (find-file-name-handler file 'vc-registered))) | 362 | (setq handler (find-file-name-handler file 'vc-registered))) |