branch: externals/ivy commit 35d1e9ad160622d75304b2d65395789718bad810 Author: Basil L. Contovounesios <ba...@contovou.net> Commit: Basil L. Contovounesios <ba...@contovou.net>
Clean up Make target scripts * .elpaignore: Remove elpa.el, which is moved under targets, and doc/scripts.el, which is deleted. * .github/workflows/test.yml: More granular build steps. * Makefile: Add copyright notice. Prefer := for internal vars. (emacs): Rename 'public' variable... (EMACS): ...to this; all uses changed. (opt-elcs): New variable holding files that depend on external packages, which need different ELCFLAGS to be built (#2583). (deps): Replace install-deps.el with new elpa.el. (test): Let ivy-test.el activate optional packages itself. (checkdoc): Run with -Q and -L. Pass source files as a list of arguments. (plain): Remove call to -version; can be inferred in other ways. Let plain.el load elpa.el itself. (obsolete): Remove; there are better ways to test byte-compiler warnings. (%.elc): Use ELCFLAGS variable. (ivy-avy.elc, ivy-hydra.elc): Use it to activate needed packages. * doc/Makefile: Add copyright notice. (INFO_INSTALL_DIR): Rename... (infodir): ...to this more conventional name. All uses changed. Let shell quote/expand $HOME variable within recipe. (ivy.info): Remove; rely on predefined implicit rule. Move --no-split argument... (MAKEINFO_FLAGS): ...to this predefined variable. (EMACS, info-src, info-dest): New variables. (INSTALL, INSTALL_DATA, RM): Define conventional variables. (info, uninstall, clean): Define conventional targets. Set info as default. (install): Mark as .PHONY. Replace cp with INSTALL_DATA. Categorize install-info as post-install step. Call install-info on installed .info file, not the srcdir one. (ivy.texi): Run Emacs with -Q. Replace scripts.el with Emacs 28 org-texinfo-export-to-texinfo-batch. * doc/scripts.el: * targets/install-deps.el: * targets/obsolete-config.el: Delete files. * elpa.el: Move... * targets/elpa.el: ...to here, incorporating functionality of install-deps.el. Enable lexical-binding. Expand copyright notice. Avoid side effects at load time. Check ELPA_STABLE before MELPA_STABLE, the idea being to eventually default to GNU ELPA instead. Improve messaging. (ivy--elpa-stable, ivy--elpa-dir, ivy--elpa-user-dir) (ivy--elpa-archive, ivy--elpa-archives, ivy--elpa-pkgs) (ivy--elpa-activated, ivy--elpa-refreshed): New variables. (ivy--elpa-activate, ivy--elpa-refresh, ivy--elpa-install-pkg) (ivy--elpa-install): New functions. * ivy-test.el: Try activating external packages. Don't print emacs-version at load time. * targets/checkdoc.el: Enable lexical-binding. Expand copyright notice. Activate external packages. Take command-line arguments. * targets/plain.el: Enable lexical-binding. Expand copyright notice. Use targets/elpa.el for installing and activating optional packages. #'-quote command symbols. When trying to load avy.el, catch only file-error. Provide targets/plain feature. --- .elpaignore | 2 - .github/workflows/test.yml | 10 ++-- Makefile | 68 ++++++++++++++---------- doc/Makefile | 58 ++++++++++++++++++--- doc/scripts.el | 6 --- elpa.el | 6 --- ivy-test.el | 7 ++- targets/checkdoc.el | 29 ++++++++--- targets/elpa.el | 125 +++++++++++++++++++++++++++++++++++++++++++++ targets/install-deps.el | 40 --------------- targets/obsolete-config.el | 5 -- targets/plain.el | 43 ++++++++++++---- 12 files changed, 285 insertions(+), 114 deletions(-) diff --git a/.elpaignore b/.elpaignore index e86fe172b6..f675cf8b37 100644 --- a/.elpaignore +++ b/.elpaignore @@ -5,7 +5,6 @@ tests .mailmap CONTRIBUTING.org Makefile -elpa.el ivy-test.el doc/Makefile @@ -13,4 +12,3 @@ doc/fdl-1.3.txt doc/gpl-3.0.txt doc/ivy.org doc/ivy-ox.el -doc/scripts.el diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ba676faef8..3d35ca029d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,7 +57,11 @@ jobs: - name: Check Emacs version run: emacs --version + - name: Dependencies + run: make deps + + - name: Compile + run: make + - name: Test - run: | - make deps - make test + run: make test diff --git a/Makefile b/Makefile index a823ddeea6..0fbb6213bf 100644 --- a/Makefile +++ b/Makefile @@ -1,53 +1,67 @@ -emacs ?= emacs +# Build and test Ivy from a source checkout. + +# Copyright (C) 2015-2025 Free Software Foundation, Inc. +# +# This file is part of GNU Emacs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +EMACS ?= emacs RM ?= rm -f -src-elcs = \ +opt-elcs := \ + ivy-avy.elc \ + ivy-hydra.elc + +src-elcs := \ colir.elc \ ivy-faces.elc \ ivy-overlay.elc \ ivy.elc \ - ivy-avy.elc \ - ivy-hydra.elc \ swiper.elc \ - counsel.elc + counsel.elc \ + $(opt-elcs) -test-elcs = ivy-test.elc +test-elcs := ivy-test.elc .PHONY: all all: compile .PHONY: deps deps: - $(emacs) -Q -batch -l targets/install-deps.el + $(EMACS) -Q -batch -l targets/elpa.el -f ivy--elpa-install + +.PHONY: compile +compile: $(src-elcs) .PHONY: test test: compile $(test-elcs) - $(emacs) -Q -batch -l elpa.el -L . -l ivy-test -f ivy-test-run-tests + $(EMACS) -Q -batch -L . $(test-elcs:%.elc=-l %) -f ivy-test-run-tests + +.PHONY: clean +clean: + $(RM) $(src-elcs) $(test-elcs) .PHONY: checkdoc checkdoc: - $(emacs) -batch -l targets/checkdoc.el - -.PHONY: compile -compile: $(src-elcs) + $(EMACS) -Q -batch -L . -l targets/checkdoc.el $(src-elcs:c=) .PHONY: plain plain: compile - $(emacs) -version - $(emacs) -Q -l elpa.el -L . -l targets/plain.el - -.PHONY: obsolete -obsolete: - $(emacs) -batch -l targets/obsolete-config.el - -.PHONY: clean -clean: - $(RM) $(src-elcs) $(test-elcs) + $(EMACS) -Q -L . -l targets/plain.el %.elc: %.el - $(emacs) -Q -batch -L . -f batch-byte-compile $< + $(EMACS) -Q -batch -L . $(ELCFLAGS) -f batch-byte-compile $< -ivy-avy.elc: ivy-avy.el -ivy-hydra.elc: ivy-hydra.el -ivy-avy.elc ivy-hydra.elc: - $(emacs) -Q -batch -l elpa.el -L . -f batch-byte-compile $< +$(opt-elcs): ELCFLAGS += -l targets/elpa.el -f ivy--elpa-activate diff --git a/doc/Makefile b/doc/Makefile index 1d6964af2c..c6dbe40062 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,11 +1,53 @@ -INFO_INSTALL_DIR="${HOME}/git/gnu-elpa/packages/ivy" +# Build and install Ivy Info manual from Org source. -ivy.texi: ivy.org ivy-ox.el scripts.el - emacs -batch -l ivy-ox.el -l scripts.el --eval "(org-to-texi \"ivy.org\")" +# Copyright (C) 2018-2025 Free Software Foundation, Inc. +# +# This file is part of GNU Emacs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. -ivy.info: ivy.texi - makeinfo --no-split $^ +EMACS ?= emacs +INSTALL ?= install +INSTALL_DATA ?= $(INSTALL) -m 644 +MAKEINFO_FLAGS += --no-split +RM ?= rm -f +infodir ?= $${HOME}/git/gnu-elpa/packages/ivy -install: ivy.info - cp $^ $(INFO_INSTALL_DIR) - install-info --info-dir=$(INFO_INSTALL_DIR) --info-file=$^ +info-src := ivy.info +info-dest = $(infodir)/$(info-src) + +.PHONY: info +info: $(info-src) + +.PHONY: install +install: info + $(INSTALL_DATA) $(info-src) "$(infodir)" + $(POST_INSTALL) + install-info --info-dir="$(infodir)" "$(info-dest)" + +.PHONY: uninstall +uninstall: + $(PRE_UNINSTALL) + install-info --delete --info-dir="$(infodir)" "$(info-dest)" + $(NORMAL_UNINSTALL) + $(RM) "$(info-dest)" + +.PHONY: clean +clean: + $(RM) $(info-src) + +ivy.texi: ivy.org ivy-ox.el + $(EMACS) -Q -batch -l ivy-ox.el \ + -eval '(setq org-confirm-babel-evaluate nil)' \ + -f org-texinfo-export-to-texinfo-batch $< $@ diff --git a/doc/scripts.el b/doc/scripts.el deleted file mode 100644 index 97b1827af6..0000000000 --- a/doc/scripts.el +++ /dev/null @@ -1,6 +0,0 @@ -;; Copyright (C) 2020-2025 Free Software Foundation, Inc. -(setq org-confirm-babel-evaluate nil) -(defun org-to-texi (fname) - (find-file fname) - (setq-default indent-tabs-mode nil) - (org-texinfo-export-to-texinfo)) diff --git a/elpa.el b/elpa.el deleted file mode 100644 index 86ec715629..0000000000 --- a/elpa.el +++ /dev/null @@ -1,6 +0,0 @@ -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. -(setq package-user-dir - (expand-file-name - (format "~/.elpa/%s/elpa" - (concat emacs-version (when (getenv "MELPA_STABLE") "-stable"))))) -(package-initialize) diff --git a/ivy-test.el b/ivy-test.el index f3d9271e90..6e0a4dfd16 100644 --- a/ivy-test.el +++ b/ivy-test.el @@ -26,6 +26,11 @@ ;;; Code: +;; Optional dependencies. +(and (require 'targets/elpa nil t) + (fboundp 'ivy--elpa-activate) + (ivy--elpa-activate)) + (defvar ivy-empty "tests/find-file/empty-dir/") (defvar ivy-features nil @@ -49,8 +54,6 @@ Intended as :after-while advice for `require'." (require 'ert) -(message "%s" (emacs-version)) - (setq ivy-last (make-ivy-state)) (ert-deftest ivy--lazy-load-ffap--ffap-url-p () diff --git a/targets/checkdoc.el b/targets/checkdoc.el index 8d27423b14..f2edba78f6 100644 --- a/targets/checkdoc.el +++ b/targets/checkdoc.el @@ -1,7 +1,24 @@ +;;; targets/checkdoc.el --- Batch mode checkdoc-file -*- lexical-binding: t -*- + ;; Copyright (C) 2017-2025 Free Software Foundation, Inc. -(checkdoc-file "colir.el") -(checkdoc-file "counsel.el") -(checkdoc-file "ivy-overlay.el") -(checkdoc-file "ivy-test.el") -(checkdoc-file "ivy.el") -(checkdoc-file "swiper.el") + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'targets/elpa) +(ivy--elpa-activate) + +(while command-line-args-left + (checkdoc-file (pop command-line-args-left))) diff --git a/targets/elpa.el b/targets/elpa.el new file mode 100644 index 0000000000..e80dc6a981 --- /dev/null +++ b/targets/elpa.el @@ -0,0 +1,125 @@ +;;; targets/elpa.el --- Optional Ivy dependencies -*- lexical-binding: t -*- + +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'package) + +(defvar ivy--elpa-stable + (or (getenv "ELPA_STABLE") + (getenv "MELPA_STABLE")) + "Non-nil if GNU ELPA should be used instead of GNU-devel ELPA.") + +(defvar ivy--elpa-dir "~/.elpa" + "Parent directory for installing optional dependencies.") + +(defvar ivy--elpa-user-dir + (expand-file-name + (format "%s%s/elpa" emacs-version (if ivy--elpa-stable "-stable" "")) + ivy--elpa-dir) + "Instance-specific value for `package-user-dir'.") + +;; FIXME: Switch to `gnu' once https://bugs.gnu.org/76264 is resolved. +(defvar ivy--elpa-archive 'melpa + "Preferred ELPA archive; keys `ivy--elpa-archives'.") + +(defvar ivy--elpa-archives + ;; Check default value rather than `gnutls-available-p': even when + ;; the latter is non-nil my Emacs 24.5 fails with https://. + (let ((s (if (string-prefix-p "https" (cdar package-archives)) "s" ""))) + `((gnu + ("gnu" . ,(format "http%s://elpa.gnu.org/%s/" + s (if ivy--elpa-stable "packages" "devel"))) + ;; For `wgrep'. + ("nongnu" . ,(format "http%s://elpa.nongnu.org/nongnu%s/" + s (if ivy--elpa-stable "" "-devel")))) + (melpa + ("melpa" . ,(format "https://%smelpa.org/packages/" + (if ivy--elpa-stable "stable." "")))))) + "Map ELPA archive symbols to their `package-archives'.") + +(defvar ivy--elpa-pkgs + '(avy + hydra + wgrep) + "List of optional (or development) package dependencies.") + +(defvar ivy--elpa-activated nil + "Non-nil if `ivy--elpa-activate' succeeded.") + +(defvar ivy--elpa-refreshed nil + "Non-nil if `ivy--elpa-refresh' succeeded.") + +(defun ivy--elpa-activate () + "Ensure packages under `ivy--elpa-dir' are activated." + (unless ivy--elpa-activated + (setq package-user-dir ivy--elpa-user-dir) + (let ((msg (format "Activating packages in %s" package-user-dir))) + (message "%s..." msg) + (package-initialize) + (message "%s...done" msg)) + (setq ivy--elpa-activated t))) + +(defun ivy--elpa-refresh () + "Ensure archive contents are refreshed." + (defvar gnutls-algorithm-priority) + (unless ivy--elpa-refreshed + (let ((archive ivy--elpa-archive)) + (setq package-archives (cdr (assq archive ivy--elpa-archives))) + (and (eq archive 'melpa) + (version< emacs-version "26.3") + ;; See https://melpa.org/#/getting-started. + (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))) + (package-refresh-contents) + (setq ivy--elpa-refreshed (and package-archive-contents t)))) + +(defun ivy--elpa-install-pkg (pkg) + "Compatibility shim for Emacs 25 `package-install'." + (condition-case nil + (package-install pkg t) + (wrong-number-of-arguments + (package-install pkg)))) + +(defun ivy--elpa-install () + "Install any missing `ivy--elpa-pkgs' with demoted errors." + (ivy--elpa-activate) + (ivy--elpa-refresh) + (let ((msg-all (format "Installing in %s" package-user-dir)) + any-ok any-err) + (message "%s..." msg-all) + (dolist (pkg ivy--elpa-pkgs) + (unless (package-installed-p pkg) + (let ((msg (format "Installing %s" pkg)) + err) + (message "%s..." msg) + (condition-case-unless-debug e + (ivy--elpa-install-pkg pkg) + (error (message "Error: %s" (error-message-string e)) + (message "%s...INCOMPLETE" msg) + (setq any-err t) + (setq err e))) + (unless err + (message "%s...done" msg) + (setq any-ok t))))) + (message "%s...%s" msg-all + (cond (any-err "INCOMPLETE") + (any-ok "done") + (t "already present"))))) + +;; TODO: upgrade-deps target? + +(provide 'targets/elpa) diff --git a/targets/install-deps.el b/targets/install-deps.el deleted file mode 100644 index af12419ab5..0000000000 --- a/targets/install-deps.el +++ /dev/null @@ -1,40 +0,0 @@ -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. -(setq melpa-stable (getenv "MELPA_STABLE")) -(setq package-user-dir - (expand-file-name - (format "~/.elpa/%s/elpa" - (concat emacs-version (when melpa-stable "-stable"))))) -(message "installing in %s ...\n" package-user-dir) -(package-initialize) -(setq package-archives - (list (if melpa-stable - '("melpa-stable" . "https://stable.melpa.org/packages/") - '("melpa" . "https://melpa.org/packages/")) - ;; '("gnu" . "https://elpa.gnu.org/packages/") - )) -(package-refresh-contents) - -(defconst ivy-dev-packages - '(avy - hydra - wgrep)) - -(dolist (package ivy-dev-packages) - (if (package-installed-p package) - (message "%S: OK" package) - (condition-case nil - (progn - (package-install package) - (message "%S: ...OK" package)) - (error - (message "%S: FAIL" package))))) - -(save-window-excursion - (package-list-packages t) - (condition-case nil - (progn - (package-menu-mark-upgrades) - (package-menu-execute t)) - (error - (message "All packages up to date")))) -(provide 'targets/install-deps) diff --git a/targets/obsolete-config.el b/targets/obsolete-config.el deleted file mode 100644 index aa6c0677f1..0000000000 --- a/targets/obsolete-config.el +++ /dev/null @@ -1,5 +0,0 @@ -;; Copyright (C) 2016-2025 Free Software Foundation, Inc. -(add-to-list 'load-path (directory-file-name default-directory)) -(require 'counsel) -(ivy-set-display-transformer 'ivy-switch-buffer #'ivy-switch-buffer-transformer) -(byte-compile-file (expand-file-name "targets/obsolete-config.el")) diff --git a/targets/plain.el b/targets/plain.el index 44a68f099d..2a3cbf4f3b 100644 --- a/targets/plain.el +++ b/targets/plain.el @@ -1,18 +1,43 @@ +;;; targets/plain.el --- Canned Ivy configuration -*- lexical-binding: t -*- + ;; Copyright (C) 2017-2025 Free Software Foundation, Inc. -;; (package-initialize) + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + (require 'counsel) +(require 'targets/elpa) + (ivy-mode) (counsel-mode) + (setq enable-recursive-minibuffers t) -(global-set-key (kbd "C-c C-r") 'ivy-resume) -(global-set-key (kbd "C-s") 'swiper) -(global-set-key (kbd "C-c j") 'counsel-git-grep) -(global-set-key (kbd "C-c k") 'counsel-rg) -(global-set-key (kbd "<f2> j") 'counsel-set-variable) -(global-set-key (kbd "C-c s") 'isearch-forward-regexp) (setq ivy-use-virtual-buffers t) + +(global-set-key (kbd "C-c C-r") #'ivy-resume) +(global-set-key (kbd "C-s") #'swiper) +(global-set-key (kbd "C-c j") #'counsel-git-grep) +(global-set-key (kbd "C-c k") #'counsel-rg) +(global-set-key (kbd "<f2> j") #'counsel-set-variable) +(global-set-key (kbd "C-c s") #'isearch-forward-regexp) + +(ivy--elpa-activate) (condition-case nil (require 'ivy-avy) - (error - (require 'targets/install-deps) + (file-error + (ivy--elpa-install) (require 'ivy-avy))) + +(provide 'targets/plain)