Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: tarsius/packed
base: 893d443089
head fork: tarsius/packed
compare: 9117d4aa97
Checking mergeability… Don't worry, you can still create the pull request.
  • 5 commits
  • 1 file changed
  • 0 commit comments
  • 1 contributor
Showing with 76 additions and 25 deletions.
  1. +76 −25 packed.el
101 packed.el
@@ -80,14 +80,6 @@ This uses the variables `load-suffixes' and `load-file-rep-suffixes'."
"Return the valid suffixes of Emacs libraries as a regular expression."
(concat (regexp-opt (packed-el-suffixes nil t)) "\\'"))
-(defun packed-source-file-p (file)
- "Return non-nil if FILE is an Emacs source file.
-More precisely return non-nil if FILE has an appropriate suffix.
-Also see `packed-library-p' which is more restrictive."
- (and (save-match-data (string-match (packed-el-regexp) file))
- (not (backup-file-name-p file))
- (not (auto-save-file-name-p file))))
(defun packed-source-file (elc)
"Return the Emacs source file for byte-compile destination ELC."
(let ((standard (concat (file-name-sans-extension
@@ -99,29 +91,53 @@ Also see `packed-library-p' which is more restrictive."
(setq file nil)))
(or file standard)))
-(defvar packed-ignore-file-regexp
- "\\(^\\.\\|-pkg\\.el\\)")
+(defvar packed-ignore-library-regexp
+ "\\(^\\.\\|-pkg\\.el$\\)")
-(defun packed-ignore-file-p (file)
- (string-match packed-ignore-file-regexp
- (file-name-nondirectory file)))
+(defun packed-ignore-library-p (library)
+ (and packed-ignore-library-regexp
+ (string-match packed-ignore-library-regexp library)))
(defvar packed-ignore-directory-regexp
(defun packed-ignore-directory-p (directory)
- (string-match packed-ignore-directory-regexp
- (file-name-nondirectory
- (directory-file-name directory))))
+ (and packed-ignore-directory-regexp
+ (string-match packed-ignore-directory-regexp
+ (file-name-nondirectory
+ (directory-file-name directory)))))
+(defmacro packed-with-file (file &rest body)
+ "Execute BODY in a buffer containing the contents of FILE.
+If FILE is nil or equal to `buffer-file-name' execute BODY in the
+current buffer. Move to beginning of buffer before executing BODY."
+ (declare (indent 1) (debug t))
+ (let ((filesym (gensym "file")))
+ `(let ((,filesym ,file))
+ (save-match-data
+ (save-excursion
+ (if (and ,filesym (not (equal ,filesym buffer-file-name)))
+ (with-temp-buffer
+ (insert-file-contents ,filesym)
+ (with-syntax-table emacs-lisp-mode-syntax-table
+ ,@body))
+ (goto-char (point-min))
+ (with-syntax-table emacs-lisp-mode-syntax-table
+ ,@body)))))))
;;; Libraries.
-;; FIXME return nil for hidden and backup files, and similar
(defun packed-library-p (file &optional raw)
"Return non-nil if FILE is an Emacs source library."
- (and (packed-source-file-p file)
- (or raw (not (packed-ignore-file-p file)))))
+ (save-match-data
+ (and (string-match (packed-el-regexp) file)
+ (not (auto-save-file-name-p file))
+ (or raw
+ (let ((name (file-name-nondirectory file)))
+ (and (not (string-equal dir-locals-file name))
+ (not (packed-ignore-library-p name))
+ (packed-library-feature file)))))))
(defun packed-locate-library (library &optional nosuffix path interactive-call)
"Show the precise file name of Emacs library LIBRARY.
@@ -177,10 +193,17 @@ files should be ignored."
(defun packed-libraries-git-1 (revision &optional raw)
(require 'magit)
- (mapcan (lambda (f)
- (when (packed-library-p f raw)
- (list f)))
- (magit-git-lines "ls-tree" "-r" "--name-only" revision)))
+ (mapcan
+ (lambda (f)
+ (when (with-temp-buffer
+ (magit-git-insert (list "show" (concat revision ":" f)))
+ (goto-char (point-min))
+ (setq buffer-file-name f)
+ (set-buffer-modified-p nil)
+ (with-syntax-table emacs-lisp-mode-syntax-table
+ (packed-library-p f raw)))
+ (list f)))
+ (magit-git-lines "ls-tree" "-r" "--name-only" revision)))
(defun packed-mainfile (directory &optional name noerror)
(packed-mainfile-1 (or name (file-name-nondirectory
@@ -218,13 +241,13 @@ files should be ignored."
(setq load-path (delete path load-path)))
(packed-load-path directory)))
-(defun packed-load-path (directory)
+(defun packed-load-path (directory &optional lax)
(let (lp in-lp)
(dolist (f (directory-files directory t))
(cond ((member (file-name-nondirectory f) '("." "..")))
((file-regular-p f)
(and (not in-lp)
- (packed-library-p f)
+ (packed-library-p f lax)
(add-to-list 'lp (directory-file-name directory))
(setq in-lp t)))
((file-directory-p f)
@@ -324,6 +347,34 @@ files should be ignored."
(add-to-list 'features (intern feature))))))
+(defun packed-library-feature (file)
+ "Return the first valid feature actually provided by FILE.
+Here valid means that requiring that feature would actually load FILE.
+Normally that is the case when the feature matches the filename, e.g.
+when \"foo.el\" provides `foo'. But if \"foo.el\"s parent directory's
+filename is \"bar\" then `bar/foo' would also be valid. Of course this
+depends on the actual value of `load-path', here we just assume that it
+allows for file to be found.
+This can be used to determine if an Emacs lisp file should be considered
+a library. Not every Emacs lisp file has to provide a feature / be a
+library. If a file lacks an expected feature then loading it using
+`require' still succeeds but causes an error."
+ (let ((features (packed-with-file file (packed-provided)))
+ feature)
+ (setq file (file-name-sans-extension
+ (file-name-sans-extension file)))
+ (while features
+ (setq feature (pop features))
+ (if (or (eq feature (intern (file-name-nondirectory file)))
+ (string-match (concat (convert-standard-filename
+ (symbol-name feature)) "$")
+ file))
+ (setq features nil)
+ (setq feature nil)))
+ feature))
(defconst packed-required-regexp "\

No commit comments for this range

Something went wrong with that request. Please try again.