summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorStefan Kangas <stefankangas@gmail.com>2022-12-26 06:30:21 +0100
committerStefan Kangas <stefankangas@gmail.com>2022-12-26 06:30:21 +0100
commit419ca81809c2eda9c9f102b7da820a6eb9685cc8 (patch)
tree4320cb1d05bb999ad2752a426d93aae991b31649 /lisp/emacs-lisp
parent48db8b68a8eb5c12d5682f2eb31cadc53186f5d7 (diff)
parent6c00d126e7fe1f6e42a0c9454c2ab4a29dcd5989 (diff)
downloademacs-419ca81809c2eda9c9f102b7da820a6eb9685cc8.tar.gz
emacs-419ca81809c2eda9c9f102b7da820a6eb9685cc8.tar.bz2
emacs-419ca81809c2eda9c9f102b7da820a6eb9685cc8.zip
Merge from origin/emacs-29
6c00d126e7f Remove remaining mentions of 'eval-current-buffer' 1073e96170b ; * doc/lispref/text.texi (Database): Fix a typo. (Bug#6... b1e68a33d89 Update to Org 9.6-61-g63e073f dad73e4de19 ; Review and fix NEWS and related documentation 72786ae237e ; Restore ARGS argument in c-ts-mode--fontify-declarator 940ab2423ca ; Always consider :lisp-dir when locating main file of VC... 9ab98cd42aa Add heuristic to locate lisp code in source packages dda011c78d1 ; * doc/lispref/parsing.texi (Tree-sitter major modes): F... d62b634d8fc ; * src/process.c (Fprocess_running_child_p): Doc fix. f6c5b3d635e ; * doc/lispref/parsing.texi: Add a reminder. e6c49c0454e ; Fix byte-copmiler warning in c-ts-mode--fontify-declarator 4234033a47a ; * lisp/treesit.el: Add some comments. 79584a206b9 Further generalize treesit-defun functions a819ca5a93c Generalize treesit-defun functions to "things" e8b34109eeb Reorder optional arguments to 'package-vc-install' b38e56d8a98 Handle missing dependencies for source packages 7bc7b6b4dd9 ; Partial revert of f3e7820b 2cec78254ea ; * nt/INSTALL.W64: Fix wording. ecee3bd4209 ; Fix recent changes in treesit documentation # Conflicts: # etc/NEWS
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/edebug.el6
-rw-r--r--lisp/emacs-lisp/package-vc.el263
-rw-r--r--lisp/emacs-lisp/package.el2
-rw-r--r--lisp/emacs-lisp/subr-x.el5
4 files changed, 178 insertions, 98 deletions
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 67704bdb51c..9e792889c89 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -92,9 +92,9 @@ using, but only when you also use Edebug."
;;;###autoload
(defcustom edebug-all-defs nil
"If non-nil, evaluating defining forms instruments for Edebug.
-This applies to `eval-defun', `eval-region', `eval-buffer', and
-`eval-current-buffer'. `eval-region' is also called by
-`eval-last-sexp', and `eval-print-last-sexp'.
+This applies to `eval-defun', `eval-region' and `eval-buffer'.
+`eval-region' is also called by `eval-last-sexp', and
+`eval-print-last-sexp'.
You can use the command `edebug-all-defs' to toggle the value of this
variable. You may wish to make it local to each buffer with
diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el
index 8f0eedd2f88..b01f87d0494 100644
--- a/lisp/emacs-lisp/package-vc.el
+++ b/lisp/emacs-lisp/package-vc.el
@@ -131,7 +131,7 @@ the `clone' function."
((null spec)
(package-vc-install name))
((stringp spec)
- (package-vc-install name nil spec))
+ (package-vc-install name spec))
((listp spec)
(package-vc--archives-initialize)
(package-vc--unpack (cadr pkg-descs) spec)))))))
@@ -306,7 +306,9 @@ asynchronously."
(directory (file-name-concat
(or (package-desc-dir pkg-desc)
(expand-file-name name package-user-dir))
- (plist-get pkg-spec :lisp-dir)))
+ (plist-get pkg-spec :lisp-dir)
+ (and-let* ((extras (package-desc-extras pkg-desc)))
+ (alist-get :lisp-dir extras))))
(file (or (plist-get pkg-spec :main-file)
(expand-file-name
(concat name ".el")
@@ -406,99 +408,156 @@ otherwise it's assumed to be an Info file."
(when clean-up
(delete-file file))))
+(defun package-vc-install-dependencies (requirements)
+ "Install missing dependencies, and return missing ones.
+The return value will be nil if everything was found, or a list
+of (NAME VERSION) pairs of all packages that couldn't be found.
+
+REQUIREMENTS should be a list of additional requirements; each
+element in this list should have the form (PACKAGE VERSION-LIST),
+where PACKAGE is a package name and VERSION-LIST is the required
+version of that package."
+ (let ((to-install '()) (missing '()))
+ (cl-labels ((search (pkg)
+ "Attempt to find all dependencies for PKG."
+ (cond
+ ((assq (car pkg) to-install)) ;inhibit cycles
+ ((package-installed-p (car pkg)))
+ ((let* ((pac package-archive-contents)
+ (desc (cadr (assoc (car pkg) pac))))
+ (if desc
+ (let ((reqs (package-desc-reqs pkg)))
+ (push pkg to-install)
+ (mapc #'search reqs))
+ (push pkg missing))))))
+ (version-order (a b)
+ "Predicate to sort packages in order."
+ (version-list-< (cadr b) (cadr a)))
+ (duplicate-p (a b)
+ "Are A and B the same package?"
+ (eq (car a) (car b)))
+ (depends-on-p (target package)
+ "Does PACKAGE depend on TARGET?"
+ (or (eq target package)
+ (let* ((pac package-archive-contents)
+ (desc (cadr (assoc package pac))))
+ (seq-some
+ (apply-partially #'depends-on-p target)
+ (package-desc-reqs desc)))))
+ (dependent-order (a b)
+ (or (not (depends-on-p (car b) (car a)))
+ (depends-on-p (car a) (car b)))))
+ (mapc #'search requirements)
+ (cl-callf sort to-install #'version-order)
+ (cl-callf seq-uniq to-install #'duplicate-p)
+ (cl-callf sort to-install #'dependent-order))
+ (mapc #'package-install-from-archive to-install)
+ missing))
+
(defun package-vc--unpack-1 (pkg-desc pkg-dir)
"Prepare PKG-DESC that is already checked-out in PKG-DIR.
This includes downloading missing dependencies, generating
autoloads, generating a package description file (used to
identify a package as a VC package later on), building
documentation and marking the package as installed."
- ;; Remove any previous instance of PKG-DESC from `package-alist'
- (let ((pkgs (assq (package-desc-name pkg-desc) package-alist)))
- (when pkgs
- (setf (cdr pkgs) (seq-remove #'package-vc-p (cdr pkgs)))))
-
- ;; In case the package was installed directly from source, the
- ;; dependency list wasn't know beforehand, and they might have
- ;; to be installed explicitly.
- (let ((deps '()))
- (dolist (file (directory-files pkg-dir t "\\.el\\'" t))
- (with-temp-buffer
- (insert-file-contents file)
- (when-let* ((require-lines (lm-header-multiline "package-requires")))
- (thread-last
- (mapconcat #'identity require-lines " ")
- package-read-from-string
- package--prepare-dependencies
- (nconc deps)
- (setq deps)))))
- (dolist (dep deps)
- (cl-callf version-to-list (cadr dep)))
- (package-download-transaction
- (package-compute-transaction nil (delete-dups deps))))
-
- (let ((default-directory (file-name-as-directory pkg-dir))
- (pkg-file (expand-file-name (package--description-file pkg-dir) pkg-dir)))
- ;; Generate autoloads
- (let* ((name (package-desc-name pkg-desc))
- (auto-name (format "%s-autoloads.el" name))
- (extras (package-desc-extras pkg-desc))
- (lisp-dir (alist-get :lisp-dir extras)))
- (package-generate-autoloads
- name (file-name-concat pkg-dir lisp-dir))
- (when lisp-dir
- (write-region
- (with-temp-buffer
- (insert ";; Autoload indirection for package-vc\n\n")
- (prin1 `(load (expand-file-name
- ,(file-name-concat lisp-dir auto-name)
- (or (and load-file-name
- (file-name-directory load-file-name))
- (car load-path))))
- (current-buffer))
- (buffer-string))
- nil (expand-file-name auto-name pkg-dir))))
-
- ;; Generate package file
- (package-vc--generate-description-file pkg-desc pkg-file)
-
- ;; Detect a manual
- (when-let ((pkg-spec (package-vc--desc->spec pkg-desc))
- ((executable-find "install-info")))
- (dolist (doc-file (ensure-list (plist-get pkg-spec :doc)))
- (package-vc--build-documentation pkg-desc doc-file))))
-
- ;; Update package-alist.
- (let ((new-desc (package-load-descriptor pkg-dir)))
- ;; Activation has to be done before compilation, so that if we're
- ;; upgrading and macros have changed we load the new definitions
- ;; before compiling.
- (when (package-activate-1 new-desc :reload :deps)
- ;; FIXME: Compilation should be done as a separate, optional, step.
- ;; E.g. for multi-package installs, we should first install all packages
- ;; and then compile them.
- (package--compile new-desc)
- (when package-native-compile
- (package--native-compile-async new-desc))
- ;; After compilation, load again any files loaded by
- ;; `activate-1', so that we use the byte-compiled definitions.
- (package--reload-previously-loaded new-desc)))
-
- ;; Mark package as selected
- (package--save-selected-packages
- (cons (package-desc-name pkg-desc)
- package-selected-packages))
- (package--quickstart-maybe-refresh)
-
- ;; Confirm that the installation was successful
- (let ((main-file (package-vc--main-file pkg-desc)))
- (message "VC package `%s' installed (Version %s, Revision %S)."
- (package-desc-name pkg-desc)
- (lm-with-file main-file
- (package-strip-rcs-id
- (or (lm-header "package-version")
- (lm-header "version"))))
- (vc-working-revision main-file)))
- t)
+ (let (missing)
+ ;; Remove any previous instance of PKG-DESC from `package-alist'
+ (let ((pkgs (assq (package-desc-name pkg-desc) package-alist)))
+ (when pkgs
+ (setf (cdr pkgs) (seq-remove #'package-vc-p (cdr pkgs)))))
+
+ ;; In case the package was installed directly from source, the
+ ;; dependency list wasn't know beforehand, and they might have
+ ;; to be installed explicitly.
+ (let ((deps '()))
+ (dolist (file (directory-files pkg-dir t "\\.el\\'" t))
+ (with-temp-buffer
+ (insert-file-contents file)
+ (when-let* ((require-lines (lm-header-multiline "package-requires")))
+ (thread-last
+ (mapconcat #'identity require-lines " ")
+ package-read-from-string
+ package--prepare-dependencies
+ (nconc deps)
+ (setq deps)))))
+ (dolist (dep deps)
+ (cl-callf version-to-list (cadr dep)))
+ (setf missing (package-vc-install-dependencies (delete-dups deps)))
+ (setf missing (delq (assq (package-desc-name pkg-desc)
+ missing)
+ missing)))
+
+ (let ((default-directory (file-name-as-directory pkg-dir))
+ (pkg-file (expand-file-name (package--description-file pkg-dir) pkg-dir)))
+ ;; Generate autoloads
+ (let* ((name (package-desc-name pkg-desc))
+ (auto-name (format "%s-autoloads.el" name))
+ (extras (package-desc-extras pkg-desc))
+ (lisp-dir (alist-get :lisp-dir extras)))
+ (package-generate-autoloads
+ name (file-name-concat pkg-dir lisp-dir))
+ (when lisp-dir
+ (write-region
+ (with-temp-buffer
+ (insert ";; Autoload indirection for package-vc\n\n")
+ (prin1 `(load (expand-file-name
+ ,(file-name-concat lisp-dir auto-name)
+ (or (and load-file-name
+ (file-name-directory load-file-name))
+ (car load-path))))
+ (current-buffer))
+ (buffer-string))
+ nil (expand-file-name auto-name pkg-dir))))
+
+ ;; Generate package file
+ (package-vc--generate-description-file pkg-desc pkg-file)
+
+ ;; Detect a manual
+ (when-let ((pkg-spec (package-vc--desc->spec pkg-desc))
+ ((executable-find "install-info")))
+ (dolist (doc-file (ensure-list (plist-get pkg-spec :doc)))
+ (package-vc--build-documentation pkg-desc doc-file))))
+
+ ;; Update package-alist.
+ (let ((new-desc (package-load-descriptor pkg-dir)))
+ ;; Activation has to be done before compilation, so that if we're
+ ;; upgrading and macros have changed we load the new definitions
+ ;; before compiling.
+ (when (package-activate-1 new-desc :reload :deps)
+ ;; FIXME: Compilation should be done as a separate, optional, step.
+ ;; E.g. for multi-package installs, we should first install all packages
+ ;; and then compile them.
+ (package--compile new-desc)
+ (when package-native-compile
+ (package--native-compile-async new-desc))
+ ;; After compilation, load again any files loaded by
+ ;; `activate-1', so that we use the byte-compiled definitions.
+ (package--reload-previously-loaded new-desc)))
+
+ ;; Mark package as selected
+ (package--save-selected-packages
+ (cons (package-desc-name pkg-desc)
+ package-selected-packages))
+ (package--quickstart-maybe-refresh)
+
+ ;; Confirm that the installation was successful
+ (let ((main-file (package-vc--main-file pkg-desc)))
+ (message "VC package `%s' installed (Version %s, Revision %S).%s"
+ (package-desc-name pkg-desc)
+ (lm-with-file main-file
+ (package-strip-rcs-id
+ (or (lm-header "package-version")
+ (lm-header "version"))))
+ (vc-working-revision main-file)
+ (if missing
+ (format
+ " Failed to install the following dependencies: %s"
+ (mapconcat
+ (lambda (p)
+ (format "%s (%s)" (car p) (cadr p)))
+ missing ", "))
+ "")))
+ t))
(defun package-vc--guess-backend (url)
"Guess the VC backend for URL.
@@ -552,6 +611,20 @@ checkout. This overrides the `:branch' attribute in PKG-SPEC."
(error "There already exists a checkout for %s" name)))
(package-vc--clone pkg-desc pkg-spec pkg-dir rev)
+ ;; When nothing is specified about a `lisp-dir', then should
+ ;; heuristically check if there is a sub-directory with lisp
+ ;; files. These are conventionally just called "lisp". If this
+ ;; directory exists and contains non-zero number of lisp files, we
+ ;; will use that instead of `pkg-dir'.
+ (when-let* (((null lisp-dir))
+ (dir (expand-file-name "lisp" pkg-dir))
+ ((file-directory-p dir))
+ ((directory-files dir nil "\\`[^.].+\\.el\\'" t 1)))
+ ;; We won't use `dir', since dir is an absolute path and we
+ ;; don't want `lisp-dir' to depend on the current location of
+ ;; the package installation, ie. to break if moved around the
+ ;; file system or between installations.
+ (setq lisp-dir "lisp"))
(when lisp-dir
(push (cons :lisp-dir lisp-dir)
(package-desc-extras pkg-desc)))
@@ -661,7 +734,7 @@ If no such revision can be found, return nil."
(line-number-at-pos nil t))))))))
;;;###autoload
-(defun package-vc-install (package &optional name rev backend)
+(defun package-vc-install (package &optional rev backend name)
"Fetch a PACKAGE and set it up for using with Emacs.
If PACKAGE is a string containing an URL, download the package
@@ -685,7 +758,9 @@ the package's repository; this is only possible if NAME-OR-URL is a URL,
a string. If BACKEND is omitted or nil, the function
uses `package-vc-heuristic-alist' to guess the backend.
Note that by default, a VC package will be prioritized over a
-regular package, but it will not remove a VC package."
+regular package, but it will not remove a VC package.
+
+\(fn PACKAGE &optional REV BACKEND)"
(interactive
(progn
;; Initialize the package system to get the list of package
@@ -694,8 +769,10 @@ regular package, but it will not remove a VC package."
(let* ((name-or-url (package-vc--read-package-name
"Fetch and install package: " t))
(name (file-name-base name-or-url)))
- (list name-or-url (intern (string-remove-prefix "emacs-" name))
- (and current-prefix-arg :last-release)))))
+ (list name-or-url
+ (and current-prefix-arg :last-release)
+ nil
+ (intern (string-remove-prefix "emacs-" name))))))
(package-vc--archives-initialize)
(cond
((null package)
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 1cc978923e0..1ab70eb2fe9 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2094,7 +2094,7 @@ if all the in-between dependencies are also in PACKAGE-LIST."
(defun package-install-from-archive (pkg-desc)
"Download and install a package defined by PKG-DESC."
;; This won't happen, unless the archive is doing something wrong.
- (when (package-vc-p pkg-desc)
+ (when (eq (package-desc-kind pkg-desc) 'dir)
(error "Can't install directory package from archive"))
(let* ((location (package-archive-base pkg-desc))
(file (concat (package-desc-full-name pkg-desc)
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 4896f4c2937..415f8db52ca 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -333,7 +333,10 @@ as the new values of the bound variables in the recursive invocation."
;;;###autoload
(defun string-glyph-split (string)
"Split STRING into a list of strings representing separate glyphs.
-This takes into account combining characters and grapheme clusters."
+This takes into account combining characters and grapheme clusters:
+if compositions are enbaled, each sequence of characters composed
+on display into a single grapheme cluster is treated as a single
+indivisible unit."
(let ((result nil)
(start 0)
comp)