From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms9.migadu.com with LMTPS id QHXHFF60KWSxVgAASxT56A (envelope-from ) for ; Sun, 02 Apr 2023 18:59:10 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id uCTsE160KWRtSgEAG6o9tA (envelope-from ) for ; Sun, 02 Apr 2023 18:59:10 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 3A8C6EAC2 for ; Sun, 2 Apr 2023 18:59:09 +0200 (CEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pj12C-0007Yh-J7; Sun, 02 Apr 2023 12:58:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pj124-0007Xr-1t for emacs-orgmode@gnu.org; Sun, 02 Apr 2023 12:58:21 -0400 Received: from mout02.posteo.de ([185.67.36.66]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pj11w-00034f-I0 for emacs-orgmode@gnu.org; Sun, 02 Apr 2023 12:58:19 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 9ECEF240302 for ; Sun, 2 Apr 2023 18:58:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1680454689; bh=+bJJqlPL9o4XagJJ2R9FuGzCmmqTXJRKaiPYv3Ignew=; h=From:To:Cc:Subject:Date:From; b=Dc0JLpc+fyf2Yf/7DAtPsxCJ/NAfP4motQxndCxLX1u4WznQorOK2hSgvEPlvlVY7 Hw7pY953rrOzsNYJGMWquJ5TXnp4/NJJcUOZawy2iAhQgYELqok/DkaANMRM2ZAWqQ W3ja4umjhC1oxyXwZdjAd2+sDttPOw3tmhgEwa5pruCAtPdmZwzgDY/PCjx7jEgNY7 yxDGwX3iHdFNSjC6rtLjUIqrjHk54GhlZEaaX/j340wj6TToUqoefPC2pLcqlViPPl TT8mU45DjP7HwOqQjzTPxBvwEsCoC5Fj1Rvr1O8kdztrVvu0+iU7GAfkfiwLfE5cBf X5VJ1O92LwOnw== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4PqKwJ5syzz9rxB; Sun, 2 Apr 2023 18:58:08 +0200 (CEST) From: Ihor Radchenko To: Max Nikulin Cc: emacs-orgmode@gnu.org Subject: [PATCH v2] Add compat.el support to Org (was: [POLL] Use compat.el in Org? (was: Useful package? Compat.el)) In-Reply-To: References: <87sfx7degz.fsf@gmail.com> <87v8ks6rhf.fsf@localhost> <87r0t3gahd.fsf@localhost> Date: Sun, 02 Apr 2023 17:00:32 +0000 Message-ID: <87wn2ujk27.fsf@localhost> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=185.67.36.66; envelope-from=yantar92@posteo.net; helo=mout02.posteo.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN ARC-Seal: i=1; s=key1; d=yhetil.org; t=1680454749; a=rsa-sha256; cv=none; b=ty/EvvEvlL6Js/DT1lUICHyZjhFRMdPTJZJlFdzRaU4Xkoxt6miiiZFZ8F8mn1uDOHncrY tfRI2SZLKM6UDaRq4qHN++ivjFBTgPmmhCSuOxMEh9sBLNmOAMW6OgB/bcmmuZzFKn38/z xuJAszT7epL5D45TckeUXaYvJcT+Fml70k3c0M4IIdXckav0dLWk8Cqn1MX1klEV49KNBr sgdSrFPJgIIKc8YUwf3Oq4ytiHlDl1DgqDrH8cjcc64Y8CmcsOacrNv3y+DpM4ESrxACSU UBZP60rcrAgp1YniMWrvx2HqqZngNw+f3c4LuA3lfx9D5VQvyq525CIrod5PRQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=posteo.net header.s=2017 header.b=Dc0JLpc+; dmarc=pass (policy=none) header.from=posteo.net; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1680454749; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=cvGivnVG5AUkhxQVJPVR2S7cfnjKdaLydPjxOSwn+O4=; b=ZqpixZfjYG40R0ow/sV3pUOs6Vx67vFch6QTIl9PL/89r1F8WBcOKDiuH5wN+35oNZT6hx 5X004A0yWeN4fnPlQWBX6UPgcB8aP7fbKRBN65n/+8n4OIeTvgLnvmvZBbOuUvW/+kJ/8y bCH6Cxh5pQKRRRMzZZrWbrI8PDC+wTN4MI9353TN13GHN6rxdrWMgMXw4YIOO78dbAXMqn JSe9wfRhl2KIYGW5sA05glIRkKSkvNYJ9LF0UQvJG78ntTBeHVaFE/pnAYKzYp/ILQkmPO sau7ELC41YD96YpQIS84VY+lYLH4Iu3jXjha99R0GbkguJdGVqQDYyoF3UZEtA== X-Migadu-Spam-Score: -4.74 X-Migadu-Scanner: scn1.migadu.com Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=posteo.net header.s=2017 header.b=Dc0JLpc+; dmarc=pass (policy=none) header.from=posteo.net; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Spam-Score: -4.74 X-Migadu-Queue-Id: 3A8C6EAC2 X-TUID: 2DaM4v2ZMeQA --=-=-= Content-Type: text/plain I am attaching a slightly tweaked version of the patch that will make less use of internet connection (use only when really, really necessary), fixes variable expansion to be done once instead of in every make sub-process, and adds some extra info messages. Max Nikulin writes: > Ihor, do added makefile rules follow best practices used by other Emacs > packages in respect to dependencies? I know no other Emacs packages that manage dependencies using make. > I do not like the idea of network queries on every make. Any better suggestions? > In some cases I would prefer to specify a directory where compat.el is > installed, so Makefile should not try to manage this directory. Sure. See EFLAGS variable. Makefile will not try to manage -L /path/to/compat directory. > Originally I expected that either compat.el would be included into Org > repository either as a copy of the file or as git submodule. That will create maintenance nightmare. > In addition I am afraid of recursive removal of directories. It is too > easy to remove too much. > >> +pkgdir = $(shell pwd)/pkg-deps > > Make has CURDIR variable, but I am unsure if it is safe to use it in > this context. Actually, we need pkgdir := $(shell pwd)/pkg-deps. CURDIR is wrong because default.mk will trigger evaluation in every make sub-process as well. >> + -$(FIND) $(pkgdir) \( -name \*.elc \) -exec $(RM) {} + > > find has -delete action. I see that "-exec $(RM)" is already used. I just copied the existing code. I guess we can use -delete as well. I do not have a lot of experience with this usage of find. May you share the equivalent find call with -delete that works with this patch? >> +cleanpkg: >> + -$(RMR) $(pkgdir) > > Perhaps it is impossible to completely avoid recursive deleting of > directories, but I still afraid of cases like > https://github.com/MrMEEE/bumblebee-Old-and-abbandoned/issues/123 > https://news.ycombinator.com/item?id=9254876 I do not think that we have any significant risk here. I would not mind alternative way to implement clean target though. If you know one. >> Subject: [PATCH 2/3] Use compat.el library instead of ad-hoc compatibility >> function set > > It would be easier to review if this patch was split into 2 parts: > - add compat.el dependency (unused) > - replace functions to ones from compat.el Sure, but after spending half an hour trying to decouple this part, I gave up and decided to leave it as is. And there is nothing fancy in adding compat dependency in 2/3 patch anyway. Just one (require 'compat nil t), two macro definitions adviced by compat manual (copy-paste from compat code), and adding compat to EPACKAGES in makefiles. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Upgrade-Org-build-system-to-handle-third-party-depen.patch >From f95433f53878e8371bb28a045fdb5d06cf0877b9 Mon Sep 17 00:00:00 2001 Message-Id: From: Ihor Radchenko Date: Sat, 1 Apr 2023 12:00:48 +0200 Subject: [PATCH 1/6] Upgrade Org build system to handle third-party dependencies * mk/default.mk (pkgdir): New variable holding the location of third-party packages to be downloaded if necessary during compilation. (EFLAGS): New variable holding extra flags to be passed to Emacs executable when running make. (EPACKAGES): List of packages to be installed (unless already present in the `load-path') during compilation. (package-install): (INSTALL_PACKAGES): New command to download and install missing packages. (BATCH): Update, setting default package location to pkgdir. * mk/targets.mk (uppkg): New target to download install missing packages. (check test): (compile compile-dirty): Use the new uppkg target. (cleanpkg): New target cleaning up the downloaded packages. (cleanall): Use the new target. (.PHONY): (CONF_BASE): (CONF_DEST): (CONF_CALL): Update according to the new variables and targets. * .gitignore: Ignore the downloaded packages. This commit paves the way towards third-party built-time dependencies for Org. In particular, towards including compat.el dependency. According to EPACKAGES, we can auto-download necessary packages, unless they are manually specified via -L switches in EFLAGS. Link: https://orgmode.org/list/87v8ks6rhf.fsf@localhost --- .gitignore | 1 + mk/default.mk | 24 +++++++++++++++++++++++- mk/targets.mk | 24 ++++++++++++++++-------- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 4bb81c359..a58670c90 100644 --- a/.gitignore +++ b/.gitignore @@ -71,6 +71,7 @@ t auto tmp TODO +/pkg-deps # and collateral damage from Emacs diff --git a/mk/default.mk b/mk/default.mk index fa46661e8..997b22b66 100644 --- a/mk/default.mk +++ b/mk/default.mk @@ -31,6 +31,15 @@ GIT_BRANCH = TMPDIR ?= /tmp testdir = $(TMPDIR)/tmp-orgtest +# Where to store Org dependencies +pkgdir = $(shell pwd)/pkg-deps + +# Extra flags to be passed to Emacs +EFLAGS ?= + +# Third-party packages to install when running make +EPACKAGES ?= + # Configuration for testing # Verbose ERT summary by default for Emacs-28 and above. # To override: @@ -72,12 +81,22 @@ REPRO_ARGS ?= req-ob-lang = --eval '(require '"'"'ob-$(ob-lang))' lst-ob-lang = ($(ob-lang) . t) req-extra = --eval '(require '"'"'$(req))' +package-install = --eval '(unless (require '"'"'$(package) nil t) (message "%s" load-path) (package-install '"'"'$(package)))' BTEST_RE ?= \\(org\\|ob\\|ox\\) BTEST_LOAD = \ --eval '(add-to-list '"'"'load-path (concat default-directory "lisp"))' \ --eval '(add-to-list '"'"'load-path (concat default-directory "testing"))' BTEST_INIT = $(BTEST_PRE) $(BTEST_LOAD) $(BTEST_POST) +ifeq (,$(EPACKAGES)) +INSTALL_PACKAGES = +else +INSTALL_PACKAGES = \ + $(BATCH) \ + --eval '(package-refresh-contents)' \ + $(foreach package,$(EPACKAGES),$(package-install)) +endif + BTEST = $(BATCH) $(BTEST_INIT) \ -l org-batch-test-init \ --eval '(setq \ @@ -120,7 +139,10 @@ EMACSQ = $(EMACS) -Q # Using emacs in batch mode. BATCH = $(EMACSQ) -batch \ - --eval '(setq vc-handled-backends nil org-startup-folded nil org-element-cache-persistent nil)' + $(EFLAGS) \ + --eval '(setq vc-handled-backends nil org-startup-folded nil org-element-cache-persistent nil)' \ + --eval '(make-directory "$(pkgdir)" t)' \ + --eval '(setq package-user-dir "$(pkgdir)")' --eval '(package-initialize)' # Emacs must be started in toplevel directory BATCHO = $(BATCH) \ diff --git a/mk/targets.mk b/mk/targets.mk index 0bd293d68..ab8b830bb 100644 --- a/mk/targets.mk +++ b/mk/targets.mk @@ -27,21 +27,21 @@ ifneq ($(GITSTATUS),) GITVERSION := $(GITVERSION:.dirty=).dirty endif -.PHONY: all oldorg update update2 up0 up1 up2 single $(SUBDIRS) \ +.PHONY: all oldorg update update2 up0 up1 up2 uppkg single $(SUBDIRS) \ check test install $(INSTSUB) \ info html pdf card refcard doc docs \ autoloads cleanall clean $(CLEANDIRS:%=clean%) \ clean-install cleanelc cleandirs \ - cleanlisp cleandoc cleandocs cleantest \ + cleanlisp cleandoc cleandocs cleantest cleanpkg \ compile compile-dirty uncompiled \ config config-test config-exe config-all config-eol config-version \ vanilla repro -CONF_BASE = EMACS DESTDIR ORGCM ORG_MAKE_DOC -CONF_DEST = lispdir infodir datadir testdir +CONF_BASE = EMACS DESTDIR ORGCM ORG_MAKE_DOC EPACKAGES +CONF_DEST = lispdir infodir datadir testdir pkgdir CONF_TEST = BTEST_PRE BTEST_POST BTEST_OB_LANGUAGES BTEST_EXTRA BTEST_RE CONF_EXEC = CP MKDIR RM RMR FIND CHMOD SUDO PDFTEX TEXI2PDF TEXI2HTML MAKEINFO INSTALL_INFO -CONF_CALL = BATCH BATCHL ELC ELCDIR NOBATCH BTEST MAKE_LOCAL_MK MAKE_ORG_INSTALL MAKE_ORG_VERSION +CONF_CALL = BATCH BATCHL ELC ELCDIR NOBATCH INSTALL_PACKAGES BTEST MAKE_LOCAL_MK MAKE_ORG_INSTALL MAKE_ORG_VERSION config-eol:: EOL = \# config-eol:: config-all config config-all:: @@ -86,7 +86,7 @@ local.mk: all compile:: $(foreach dir, doc lisp, $(MAKE) -C $(dir) clean;) -compile compile-dirty:: +compile compile-dirty:: uppkg $(MAKE) -C lisp $@ all clean-install:: $(foreach dir, $(SUBDIRS), $(MAKE) -C $(dir) $@;) @@ -94,7 +94,7 @@ all clean-install:: vanilla: -@$(NOBATCH) & -check test:: compile +check test:: uppkg compile check test test-dirty:: -$(MKDIR) $(testdir) TMPDIR=$(testdir) $(BTEST) @@ -102,6 +102,11 @@ ifeq ($(TEST_NO_AUTOCLEAN),) # define this variable to leave $(testdir) around f $(MAKE) cleantest endif +uppkg:: + -$(MKDIR) -p $(pkgdir) + -$(FIND) $(pkgdir) \( -name \*.elc \) -exec $(RM) {} + + $(INSTALL_PACKAGES) + up0 up1 up2:: git checkout $(GIT_BRANCH) git remote update @@ -134,7 +139,7 @@ cleandirs: clean: cleanlisp cleandoc -cleanall: cleandirs cleantest +cleanall: cleandirs cleantest cleanpkg -$(FIND) . \( -name \*~ -o -name \*# -o -name .#\* \) -exec $(RM) {} + -$(FIND) $(CLEANDIRS) \( -name \*~ -o -name \*.elc \) -exec $(RM) {} + @@ -159,3 +164,6 @@ cleantest: $(FIND) $(testdir) -type d -exec $(CHMOD) u+w {} + && \ $(RMR) $(testdir) ; \ } + +cleanpkg: + -$(RMR) $(pkgdir) -- 2.39.1 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-Use-compat.el-library-instead-of-ad-hoc-compatibilit.patch >From 6099628c54170b515d8812428fa050f81c0533ec Mon Sep 17 00:00:00 2001 Message-Id: <6099628c54170b515d8812428fa050f81c0533ec.1680454654.git.yantar92@posteo.net> In-Reply-To: References: From: Ihor Radchenko Date: Sat, 1 Apr 2023 12:10:13 +0200 Subject: [PATCH 2/6] Use compat.el library instead of ad-hoc compatibility function set * mk/default.mk (EPACKAGES): Demand compat library during compile time. * lisp/org.el: Add compat dependency. (org-fill-paragraph): * lisp/org-compat.el: Implement compat.el compatibility layer. Obsolete org-* compatibility functions that are already available in compat.el: `org-file-has-changed-p', `org-string-equal-ignore-case', `org-file-name-concat', `org-directory-empty-p', `org-string-clean-whitespace', `org-format-prompt', `org-xor', `org-string-distance', `org-buffer-hash'. * lisp/ob-core.el (org-babel-results-keyword): Use functions provided by compat.el. (org-babel-insert-result): * lisp/oc-basic.el (org-cite-basic--parse-bibliography): * lisp/oc.el (org-cite-adjust-note): * lisp/ol-gnus.el (org-gnus-group-link): (org-gnus-article-link): (org-gnus-store-link): * lisp/ol.el: (org-store-link): * lisp/org-attach.el: * lisp/org-capture.el: (org-capture-fill-template): * lisp/org-fold-core.el (org-fold-core-next-visibility-change): * lisp/org-lint.el: * lisp/org-persist.el (org-persist-directory): (org-persist-read:file): (org-persist-read:url): (org-persist--load-index): (org-persist-write:file): (org-persist-write:index): (org-persist--merge-index-with-disk): (org-persist-read): (org-persist-write): (org-persist-write-all): (org-persist--gc-persist-file): (org-persist-gc): * lisp/org-refile.el (org-refile-get-location): * lisp/ox.el (org-export-resolve-radio-link): * testing/lisp/test-ol.el (test-org-link/toggle-link-display): * testing/lisp/test-org-capture.el (test-org-capture/abort): Link: https://orgmode.org/list/87v8ks6rhf.fsf@localhost --- .gitignore | 2 +- lisp/ob-core.el | 10 +- lisp/oc-basic.el | 6 +- lisp/oc.el | 2 +- lisp/ol-gnus.el | 8 +- lisp/ol.el | 4 +- lisp/org-attach.el | 2 +- lisp/org-capture.el | 8 +- lisp/org-compat.el | 220 +++++++++---------------------- lisp/org-fold-core.el | 2 +- lisp/org-lint.el | 2 +- lisp/org-persist.el | 38 +++--- lisp/org-refile.el | 2 +- lisp/org.el | 6 +- lisp/ox.el | 6 +- mk/default.mk | 2 +- testing/lisp/test-ol.el | 10 +- testing/lisp/test-org-capture.el | 2 +- 18 files changed, 118 insertions(+), 214 deletions(-) diff --git a/.gitignore b/.gitignore index a58670c90..0d9c5b297 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ local*.mk .gitattributes mk/x11idle ChangeLog +pkg-deps/ # Files generated during `make packages/org` in a clone of `elpa.git`. @@ -71,7 +72,6 @@ t auto tmp TODO -/pkg-deps # and collateral damage from Emacs diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 471887a3a..4ef1f2084 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -145,7 +145,7 @@ (defcustom org-babel-results-keyword "RESULTS" :type 'string :safe (lambda (v) (and (stringp v) - (org-string-equal-ignore-case "RESULTS" v)))) + (string-equal-ignore-case "RESULTS" v)))) (defcustom org-babel-noweb-wrap-start "<<" "String used to begin a noweb reference in a code block. @@ -927,7 +927,7 @@ (defun org-babel-check-src-block () (match-string 4)))))) (dolist (name names) (when (and (not (string= header name)) - (<= (org-string-distance header name) too-close) + (<= (string-distance header name) too-close) (not (member header names))) (error "Supplied header \"%S\" is suspiciously close to \"%S\"" header name)))) @@ -2518,7 +2518,7 @@ (defun org-babel-insert-result (result &optional result-params info hash lang ex ;; Escape contents from "export" wrap. Wrap ;; inline results within an export snippet with ;; appropriate value. - ((org-string-equal-ignore-case type "export") + ((string-equal-ignore-case type "export") (let ((backend (pcase split (`(,_) "none") (`(,_ ,b . ,_) b)))) @@ -2529,14 +2529,14 @@ (defun org-babel-insert-result (result &optional result-params info hash lang ex backend) "@@)}}}"))) ;; Escape contents from "example" wrap. Mark ;; inline results as verbatim. - ((org-string-equal-ignore-case type "example") + ((string-equal-ignore-case type "example") (funcall wrap opening-line closing-line nil nil "{{{results(=" "=)}}}")) ;; Escape contents from "src" wrap. Mark ;; inline results as inline source code. - ((org-string-equal-ignore-case type "src") + ((string-equal-ignore-case type "src") (let ((inline-open (pcase split (`(,_) diff --git a/lisp/oc-basic.el b/lisp/oc-basic.el index 12b627e71..1c86f344a 100644 --- a/lisp/oc-basic.el +++ b/lisp/oc-basic.el @@ -274,11 +274,11 @@ (defun org-cite-basic--parse-bibliography (&optional info) (dolist (file (org-cite-list-bibliography-files)) (when (file-readable-p file) (with-temp-buffer - (when (or (org-file-has-changed-p file) + (when (or (file-has-changed-p file) (not (gethash file org-cite-basic--file-id-cache))) (insert-file-contents file) (set-visited-file-name file t) - (puthash file (org-buffer-hash) org-cite-basic--file-id-cache)) + (puthash file (buffer-hash) org-cite-basic--file-id-cache)) (condition-case nil (unwind-protect (let* ((file-id (cons file (gethash file org-cite-basic--file-id-cache))) @@ -488,7 +488,7 @@ (defun org-cite-basic--close-keys (key keys) "List cite keys close to KEY in terms of string distance." (seq-filter (lambda (k) (>= org-cite-basic-max-key-distance - (org-string-distance k key))) + (string-distance k key))) keys)) (defun org-cite-basic--set-keymap (beg end suggestions) diff --git a/lisp/oc.el b/lisp/oc.el index dde6f3a32..f39ae848b 100644 --- a/lisp/oc.el +++ b/lisp/oc.el @@ -1029,7 +1029,7 @@ (defun org-cite-adjust-note (citation info &optional rule punct) (match-string 3 previous))))) ;; Bail you when there is no quote and either no punctuation, or ;; punctuation on both sides. - (when (or quote (org-xor punct final-punct)) + (when (or quote (xor punct final-punct)) ;; Phase 1: handle punctuation rule. (pcase rule ((guard (not quote)) nil) diff --git a/lisp/ol-gnus.el b/lisp/ol-gnus.el index 7c07ce045..e121cfba3 100644 --- a/lisp/ol-gnus.el +++ b/lisp/ol-gnus.el @@ -98,8 +98,8 @@ (defun org-gnus-group-link (group) `org-gnus-prefer-web-links' is reversed." (let ((unprefixed-group (replace-regexp-in-string "^[^:]+:" "" group))) (if (and (string-prefix-p "nntp" group) ;; Only for nntp groups - (org-xor current-prefix-arg - org-gnus-prefer-web-links)) + (xor current-prefix-arg + org-gnus-prefer-web-links)) (concat "https://groups.google.com/group/" unprefixed-group) (concat "gnus:" group)))) @@ -116,7 +116,7 @@ (defun org-gnus-article-link (group newsgroups message-id x-no-archive) If `org-store-link' was called with a prefix arg the meaning of `org-gnus-prefer-web-links' is reversed." - (if (and (org-xor current-prefix-arg org-gnus-prefer-web-links) + (if (and (xor current-prefix-arg org-gnus-prefer-web-links) newsgroups ;make web links only for nntp groups (not x-no-archive)) ;and if X-No-Archive isn't set (format "https://groups.google.com/groups/search?as_umsgid=%s" @@ -169,7 +169,7 @@ (defun org-gnus-store-link () newsgroups x-no-archive) ;; Fetching an article is an expensive operation; newsgroup and ;; x-no-archive are only needed for web links. - (when (org-xor current-prefix-arg org-gnus-prefer-web-links) + (when (xor current-prefix-arg org-gnus-prefer-web-links) ;; Make sure the original article buffer is up-to-date. (save-window-excursion (gnus-summary-select-article)) (setq to (or to (gnus-fetch-original-field "To"))) diff --git a/lisp/ol.el b/lisp/ol.el index 9e4781f6e..3d62a6fa0 100644 --- a/lisp/ol.el +++ b/lisp/ol.el @@ -1692,7 +1692,7 @@ (defun org-store-link (arg &optional interactive?) (abbreviate-file-name (buffer-file-name (buffer-base-buffer))))) ;; Add a context search string. - (when (org-xor org-link-context-for-files (equal arg '(4))) + (when (xor org-link-context-for-files (equal arg '(4))) (let* ((element (org-element-at-point)) (name (org-element-property :name element)) (context @@ -1724,7 +1724,7 @@ (defun org-store-link (arg &optional interactive?) (abbreviate-file-name (buffer-file-name (buffer-base-buffer))))) ;; Add a context search string. - (when (org-xor org-link-context-for-files (equal arg '(4))) + (when (xor org-link-context-for-files (equal arg '(4))) (let ((context (org-link--normalize-string (or (org-link--context-from-region) (org-current-line-string)) diff --git a/lisp/org-attach.el b/lisp/org-attach.el index 8d01eda71..5cc40873c 100644 --- a/lisp/org-attach.el +++ b/lisp/org-attach.el @@ -674,7 +674,7 @@ (defun org-attach-sync () (let ((files (org-attach-file-list attach-dir))) (org-attach-tag (not files))) (when org-attach-sync-delete-empty-dir - (when (and (org-directory-empty-p attach-dir) + (when (and (directory-empty-p attach-dir) (if (eq 'query org-attach-sync-delete-empty-dir) (yes-or-no-p "Attachment directory is empty. Delete?") t)) diff --git a/lisp/org-capture.el b/lisp/org-capture.el index b96e9f336..c5b1c6d50 100644 --- a/lisp/org-capture.el +++ b/lisp/org-capture.el @@ -1323,9 +1323,9 @@ (defun org-capture-place-item () ;; prioritize the existing list. (when prepend? (let ((ordered? (eq 'ordered (org-element-property :type item)))) - (when (org-xor ordered? - (string-match-p "\\`[A-Za-z0-9]\\([.)]\\)" - template)) + (when (xor ordered? + (string-match-p "\\`[A-Za-z0-9]\\([.)]\\)" + template)) (org-cycle-list-bullet (if ordered? "1." "-"))))) ;; Eventually repair the list for proper indentation and ;; bullets. @@ -1867,7 +1867,7 @@ (defun org-capture-fill-template (&optional template initial annotation) (setq org-capture--prompt-history (gethash prompt org-capture--prompt-history-table)) (push (org-completing-read - (org-format-prompt (or prompt "Enter string") default) + (format-prompt (or prompt "Enter string") default) completions nil nil nil 'org-capture--prompt-history default) strings) diff --git a/lisp/org-compat.el b/lisp/org-compat.el index c47a4e8c2..046a3db97 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -79,9 +79,6 @@ (declare-function org-fold-region "org-fold" (from to flag &optional spec)) (declare-function org-fold-show-all "org-fold" (&optional types)) (declare-function org-fold-show-children "org-fold" (&optional level)) (declare-function org-fold-show-entry "org-fold" (&optional hide-drawers)) -;; `org-string-equal-ignore-case' is in _this_ file but isn't at the -;; top-level. -(declare-function org-string-equal-ignore-case "org-compat" (string1 string2)) (defvar calendar-mode-map) (defvar org-complex-heading-regexp) @@ -95,104 +92,67 @@ (defvar org-table1-hline-regexp) (defvar org-fold-core-style) -;;; Emacs < 29 compatibility - -(defvar org-file-has-changed-p--hash-table (make-hash-table :test #'equal) - "Internal variable used by `org-file-has-changed-p'.") - -(if (fboundp 'file-has-changed-p) - (defalias 'org-file-has-changed-p #'file-has-changed-p) - (defun org-file-has-changed-p (file &optional tag) - "Return non-nil if FILE has changed. -The size and modification time of FILE are compared to the size -and modification time of the same FILE during a previous -invocation of `org-file-has-changed-p'. Thus, the first invocation -of `org-file-has-changed-p' always returns non-nil when FILE exists. -The optional argument TAG, which must be a symbol, can be used to -limit the comparison to invocations with identical tags; it can be -the symbol of the calling function, for example." - (let* ((file (directory-file-name (expand-file-name file))) - (remote-file-name-inhibit-cache t) - (fileattr (file-attributes file 'integer)) - (attr (and fileattr - (cons (file-attribute-size fileattr) - (file-attribute-modification-time fileattr)))) - (sym (concat (symbol-name tag) "@" file)) - (cachedattr (gethash sym org-file-has-changed-p--hash-table))) - (when (not (equal attr cachedattr)) - (puthash sym attr org-file-has-changed-p--hash-table))))) - -(if (fboundp 'string-equal-ignore-case) - (defalias 'org-string-equal-ignore-case #'string-equal-ignore-case) - ;; From Emacs subr.el. - (defun org-string-equal-ignore-case (string1 string2) - "Like `string-equal', but case-insensitive. -Upper-case and lower-case letters are treated as equal. -Unibyte strings are converted to multibyte for comparison." - (eq t (compare-strings string1 0 nil string2 0 nil t)))) - - -;;; Emacs < 28.1 compatibility - -(if (fboundp 'file-name-concat) - (defalias 'org-file-name-concat #'file-name-concat) - (defun org-file-name-concat (directory &rest components) - "Append COMPONENTS to DIRECTORY and return the resulting string. - -Elements in COMPONENTS must be a string or nil. -DIRECTORY or the non-final elements in COMPONENTS may or may not end -with a slash -- if they don't end with a slash, a slash will be -inserted before contatenating." - (save-match-data - (mapconcat - #'identity - (delq nil - (mapcar - (lambda (str) - (when (and str (not (seq-empty-p str)) - (string-match "\\(.+\\)/?" str)) - (match-string 1 str))) - (cons directory components))) - "/")))) - -(if (fboundp 'directory-empty-p) - (defalias 'org-directory-empty-p #'directory-empty-p) - (defun org-directory-empty-p (dir) - "Return t if DIR names an existing directory containing no other files." - (and (file-directory-p dir) - (null (directory-files dir nil directory-files-no-dot-files-regexp t))))) - -(if (fboundp 'string-clean-whitespace) - (defalias 'org-string-clean-whitespace #'string-clean-whitespace) - ;; From Emacs subr-x.el. - (defun org-string-clean-whitespace (string) - "Clean up whitespace in STRING. -All sequences of whitespaces in STRING are collapsed into a -single space character, and leading/trailing whitespace is -removed." - (let ((blank "[[:blank:]\r\n]+")) - (string-trim (replace-regexp-in-string blank " " string t t) - blank blank)))) - -(if (fboundp 'format-prompt) - (defalias 'org-format-prompt #'format-prompt) - ;; From Emacs minibuffer.el, inlining - ;; `minibuffer-default-prompt-format' value and replacing `length<' - ;; (both new in Emacs 28.1). - (defun org-format-prompt (prompt default &rest format-args) - "Compatibility substitute for `format-prompt'." - (concat - (if (null format-args) - prompt - (apply #'format prompt format-args)) - (and default - (or (not (stringp default)) - (> (length default) 0)) - (format " (default %s)" - (if (consp default) - (car default) - default))) - ": "))) +;;; compat.el + +;; Do not throw an error when not available - assume latest Emacs +;; version (built-in Org). +(require 'compat nil 'noerror) + +;; Provide compatibility macros when we are a part of Emacs. +;; See https://elpa.gnu.org/packages/doc/compat.html#Usage + +(defmacro org-compat-function (fun) + "Return compatibility function symbol for FUN. + +If the Emacs version provides a sufficiently recent version of +FUN, the symbol FUN is returned itself. Otherwise the macro +returns the symbol of a compatibility function which supports the +behavior and calling convention of the current stable Emacs +version. For example Compat 29.1 will provide compatibility +functions which implement the behavior and calling convention of +Emacs 29.1. + +See also `org-compat-call' to directly call compatibility functions." + (let ((compat (intern (format "compat--%s" fun)))) + `#',(if (fboundp compat) compat fun))) + +(defmacro org-compat-call (fun &rest args) + "Call compatibility function or macro FUN with ARGS. + +A good example function is `plist-get' which was extended with an +additional predicate argument in Emacs 29.1. The compatibility +function, which supports this additional argument, can be +obtained via (compat-function plist-get) and called +via (compat-call plist-get plist prop predicate). It is not +possible to directly call (plist-get plist prop predicate) on +Emacs older than 29.1, since the original `plist-get' function +does not yet support the predicate argument. Note that the +Compat library never overrides existing functions. + +See also `org-compat-function' to lookup compatibility functions." + (let ((compat (intern (format "compat--%s" fun)))) + `(,(if (fboundp compat) compat fun) ,@args))) + +;; Obsolete compatibility wrappers used before inclusion of compat.el. + +(define-obsolete-function-alias 'org-file-has-changed-p + 'file-has-changed-p "9.7") +(define-obsolete-function-alias 'org-string-equal-ignore-case + 'string-equal-ignore-case "9.7") +(define-obsolete-function-alias 'org-file-name-concat + 'file-name-concat "9.7") +(define-obsolete-function-alias 'org-directory-empty-p + 'directory-empty-p "9.7") +(define-obsolete-function-alias 'org-string-clean-whitespace + 'string-clean-whitespace "9.7") +(define-obsolete-function-alias 'org-format-prompt + 'format-prompt "9.7") +(define-obsolete-function-alias 'org-xor + 'xor "9.7") +(define-obsolete-function-alias 'org-string-distance + 'string-distance "9.7") +(define-obsolete-function-alias 'org-buffer-hash + 'buffer-hash "9.7") ;;; Emacs < 27.1 compatibility @@ -210,22 +170,6 @@ (if (version< emacs-version "27.1") (replace-buffer-contents source)) (defalias 'org-replace-buffer-contents #'replace-buffer-contents)) -(unless (fboundp 'proper-list-p) - ;; `proper-list-p' was added in Emacs 27.1. The function below is - ;; taken from Emacs subr.el 200195e824b^. - (defun proper-list-p (object) - "Return OBJECT's length if it is a proper list, nil otherwise. -A proper list is neither circular nor dotted (i.e., its last cdr -is nil)." - (and (listp object) (ignore-errors (length object))))) - -(if (fboundp 'xor) - ;; `xor' was added in Emacs 27.1. - (defalias 'org-xor #'xor) - (defsubst org-xor (a b) - "Exclusive `or'." - (if a (not b) b))) - (unless (fboundp 'pcomplete-uniquify-list) ;; The misspelled variant was made obsolete in Emacs 27.1 (defalias 'pcomplete-uniquify-list 'pcomplete-uniqify-list)) @@ -255,29 +199,6 @@ (defun org--set-faces-extend (faces extend-p) (when (fboundp 'set-face-extend) (mapc (lambda (f) (set-face-extend f extend-p)) faces))) -(if (fboundp 'string-distance) - (defalias 'org-string-distance 'string-distance) - (defun org-string-distance (s1 s2) - "Return the edit (levenshtein) distance between strings S1 S2." - (let* ((l1 (length s1)) - (l2 (length s2)) - (dist (vconcat (mapcar (lambda (_) (make-vector (1+ l2) nil)) - (number-sequence 1 (1+ l1))))) - (in (lambda (i j) (aref (aref dist i) j)))) - (setf (aref (aref dist 0) 0) 0) - (dolist (j (number-sequence 1 l2)) - (setf (aref (aref dist 0) j) j)) - (dolist (i (number-sequence 1 l1)) - (setf (aref (aref dist i) 0) i) - (dolist (j (number-sequence 1 l2)) - (setf (aref (aref dist i) j) - (min - (1+ (funcall in (1- i) j)) - (1+ (funcall in i (1- j))) - (+ (if (equal (aref s1 (1- i)) (aref s2 (1- j))) 0 1) - (funcall in (1- i) (1- j))))))) - (funcall in l1 l2)))) - (define-obsolete-function-alias 'org-babel-edit-distance 'org-string-distance "9.5") @@ -298,23 +219,6 @@ (if (fboundp 'line-number-display-width) (defalias 'org-line-number-display-width 'line-number-display-width) (defun org-line-number-display-width (&rest _) 0)) -(if (fboundp 'buffer-hash) - (defalias 'org-buffer-hash 'buffer-hash) - (defun org-buffer-hash () (md5 (current-buffer)))) - -(unless (fboundp 'file-attribute-modification-time) - (defsubst file-attribute-modification-time (attributes) - "The modification time in ATTRIBUTES returned by `file-attributes'. -This is the time of the last change to the file's contents, and -is a Lisp timestamp in the same style as `current-time'." - (nth 5 attributes))) - -(unless (fboundp 'file-attribute-size) - (defsubst file-attribute-size (attributes) - "The size (in bytes) in ATTRIBUTES returned by `file-attributes'. -This is a floating point number if the size is too large for an integer." - (nth 7 attributes))) - ;;; Obsolete aliases (remove them after the next major release). @@ -1416,7 +1320,7 @@ (defun org-mode-flyspell-verify () (and log (let ((drawer (org-element-lineage element '(drawer)))) (and drawer - (org-string-equal-ignore-case + (string-equal-ignore-case log (org-element-property :drawer-name drawer)))))) nil) (t diff --git a/lisp/org-fold-core.el b/lisp/org-fold-core.el index 43c6b2b74..c699c115b 100644 --- a/lisp/org-fold-core.el +++ b/lisp/org-fold-core.el @@ -841,7 +841,7 @@ (defun org-fold-core-next-visibility-change (&optional pos limit ignore-hidden-p (lambda (p) (next-single-char-property-change p 'invisible nil limit))))) (next pos)) (while (and (funcall cmp next limit) - (not (org-xor + (not (xor invisible-initially? (funcall invisible-p (if previous-p diff --git a/lisp/org-lint.el b/lisp/org-lint.el index 0e2967b6c..adc893aff 100644 --- a/lisp/org-lint.el +++ b/lisp/org-lint.el @@ -383,7 +383,7 @@ (defun org-lint-duplicate-custom-id (ast) ast 'node-property (lambda (property) - (and (org-string-equal-ignore-case + (and (string-equal-ignore-case "CUSTOM_ID" (org-element-property :key property)) (org-element-property :value property))) (lambda (property _) (org-element-property :begin property)) diff --git a/lisp/org-persist.el b/lisp/org-persist.el index 8e73fbc4b..21c09567f 100644 --- a/lisp/org-persist.el +++ b/lisp/org-persist.el @@ -279,12 +279,12 @@ (defgroup org-persist nil (defcustom org-persist-directory (expand-file-name - (org-file-name-concat + (file-name-concat (let ((cache-dir (when (fboundp 'xdg-cache-home) (xdg-cache-home)))) (if (or (seq-empty-p cache-dir) (not (file-exists-p cache-dir)) - (file-exists-p (org-file-name-concat + (file-exists-p (file-name-concat user-emacs-directory "org-persist"))) user-emacs-directory @@ -675,13 +675,13 @@ (defalias 'org-persist-read:version #'org-persist-read:elisp-data) (defun org-persist-read:file (_ path __) "Read file container from PATH." - (when (and path (file-exists-p (org-file-name-concat org-persist-directory path))) - (org-file-name-concat org-persist-directory path))) + (when (and path (file-exists-p (file-name-concat org-persist-directory path))) + (file-name-concat org-persist-directory path))) (defun org-persist-read:url (_ path __) "Read file container from PATH." - (when (and path (file-exists-p (org-file-name-concat org-persist-directory path))) - (org-file-name-concat org-persist-directory path))) + (when (and path (file-exists-p (file-name-concat org-persist-directory path))) + (file-name-concat org-persist-directory path))) (defun org-persist-read:index (cont index-file _) "Read index container CONT from INDEX-FILE." @@ -750,7 +750,7 @@ (defun org-persist--load-index () "Load `org-persist--index'." (org-persist-load:index `(index ,org-persist--storage-version) - (org-file-name-concat org-persist-directory org-persist-index-file) + (file-name-concat org-persist-directory org-persist-index-file) nil)) ;;;; Writing container data @@ -804,7 +804,7 @@ (defun org-persist-write:file (c collection) (setq path (cadr c))) (let* ((persist-file (plist-get collection :persist-file)) (ext (file-name-extension path)) - (file-copy (org-file-name-concat + (file-copy (file-name-concat org-persist-directory (format "%s-%s.%s" persist-file (md5 path) ext)))) (unless (file-exists-p file-copy) @@ -850,7 +850,7 @@ (defun org-persist-write:index (container _) org-persist-directory)))) (when (file-exists-p org-persist-directory) (let ((index-file - (org-file-name-concat org-persist-directory org-persist-index-file))) + (file-name-concat org-persist-directory org-persist-index-file))) (org-persist--merge-index-with-disk) (org-persist--write-elisp-file index-file org-persist--index t t) (setq org-persist--index-age @@ -865,7 +865,7 @@ (defun org-persist--save-index () (defun org-persist--merge-index-with-disk () "Merge `org-persist--index' with the current index file on disk." (let* ((index-file - (org-file-name-concat org-persist-directory org-persist-index-file)) + (file-name-concat org-persist-directory org-persist-index-file)) (disk-index (and (file-exists-p index-file) (org-file-newer-than-p index-file org-persist--index-age) @@ -887,8 +887,8 @@ (defun org-persist--merge-index (base other) (dolist (item (nreverse new)) (unless (or (memq 'index (mapcar #'car (plist-get item :container))) (not (file-exists-p - (org-file-name-concat org-persist-directory - (plist-get item :persist-file)))) + (file-name-concat org-persist-directory + (plist-get item :persist-file)))) (member (plist-get item :persist-file) base-files)) (push item combined))) (nreverse combined)) @@ -989,7 +989,7 @@ (cl-defun org-persist-read (container &optional associated hash-must-match load (let* ((collection (org-persist--find-index `(:container ,container :associated ,associated))) (persist-file (when collection - (org-file-name-concat + (file-name-concat org-persist-directory (plist-get collection :persist-file)))) (data nil)) @@ -1077,7 +1077,7 @@ (defun org-persist-write (container &optional associated ignore-return) (run-hook-with-args-until-success 'org-persist-before-write-hook v associated)) (plist-get collection :container))) (when (or (file-exists-p org-persist-directory) (org-persist--save-index)) - (let ((file (org-file-name-concat org-persist-directory (plist-get collection :persist-file))) + (let ((file (file-name-concat org-persist-directory (plist-get collection :persist-file))) (data (mapcar (lambda (c) (cons c (org-persist-write:generic c collection))) (plist-get collection :container)))) (puthash file data org-persist--write-cache) @@ -1097,11 +1097,11 @@ (defun org-persist-write-all (&optional associated) ;; The container is an `index' container. (eq 'index (caar (plist-get (car org-persist--index) :container))) (or (not (file-exists-p org-persist-directory)) - (org-directory-empty-p org-persist-directory))) + (directory-empty-p org-persist-directory))) ;; Do not write anything, and clear up `org-persist-directory' to reduce ;; clutter. (when (and (file-exists-p org-persist-directory) - (org-directory-empty-p org-persist-directory)) + (directory-empty-p org-persist-directory)) (delete-directory org-persist-directory)) ;; Write the data. (let (all-containers) @@ -1142,7 +1142,7 @@ (defun org-persist--gc-persist-file (persist-file) "Garbage collect PERSIST-FILE." (when (file-exists-p persist-file) (delete-file persist-file) - (when (org-directory-empty-p (file-name-directory persist-file)) + (when (directory-empty-p (file-name-directory persist-file)) (delete-directory (file-name-directory persist-file))))) (defmacro org-persist-associated-files:generic (container collection) @@ -1180,7 +1180,7 @@ (defun org-persist-gc () (let (new-index (remote-files-num 0) (orphan-files - (delete (org-file-name-concat org-persist-directory org-persist-index-file) + (delete (file-name-concat org-persist-directory org-persist-index-file) (when (file-exists-p org-persist-directory) (directory-files-recursively org-persist-directory ".+"))))) (dolist (collection org-persist--index) @@ -1188,7 +1188,7 @@ (defun org-persist-gc () (web-file (and file (string-match-p "\\`https?://" file))) (file-remote (when file (file-remote-p file))) (persist-file (when (plist-get collection :persist-file) - (org-file-name-concat + (file-name-concat org-persist-directory (plist-get collection :persist-file)))) (expired? (org-persist--gc-expired-p diff --git a/lisp/org-refile.el b/lisp/org-refile.el index 03c351cf6..9797a0633 100644 --- a/lisp/org-refile.el +++ b/lisp/org-refile.el @@ -666,7 +666,7 @@ (defun org-refile-get-location (&optional prompt default-buffer new-nodes) (prompt (let ((default (or (car org-refile-history) (and (assoc cbnex tbl) (setq cdef cbnex) cbnex)))) - (org-format-prompt prompt default))) + (format-prompt prompt default))) pa answ parent-target child parent old-hist) (setq old-hist org-refile-history) (setq answ (funcall cfunc prompt tbl nil (not new-nodes) diff --git a/lisp/org.el b/lisp/org.el index 10ade32dd..e9fa9a241 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -7,7 +7,7 @@ ;;; org.el --- Outline-based notes management and organizer -*- lexical-binding: ;; Maintainer: Bastien Guerry ;; Keywords: outlines, hypermedia, calendar, wp ;; URL: https://orgmode.org -;; Package-Requires: ((emacs "26.1")) +;; Package-Requires: ((emacs "26.1") (compat "29.1.4.1")) ;; Version: 9.7-pre @@ -19445,7 +19445,7 @@ (defun org-fill-paragraph (&optional justify region) (barf-if-buffer-read-only) (list (when current-prefix-arg 'full) t))) (let ((hash (and (not (buffer-modified-p)) - (org-buffer-hash)))) + (buffer-hash)))) (cond ((and region transient-mark-mode mark-active (not (eq (region-beginning) (region-end)))) @@ -19470,7 +19470,7 @@ (defun org-fill-paragraph (&optional justify region) ;; If we didn't change anything in the buffer (and the buffer was ;; previously unmodified), then flip the modification status back ;; to "unchanged". - (when (and hash (equal hash (org-buffer-hash))) + (when (and hash (equal hash (buffer-hash))) (set-buffer-modified-p nil)) ;; Return non-nil. t)) diff --git a/lisp/ox.el b/lisp/ox.el index a6169ea63..203136994 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -4626,11 +4626,11 @@ (defun org-export-resolve-radio-link (link info) Return value can be a radio-target object or nil. Assume LINK has type \"radio\"." - (let ((path (org-string-clean-whitespace (org-element-property :path link)))) + (let ((path (string-clean-whitespace (org-element-property :path link)))) (org-element-map (plist-get info :parse-tree) 'radio-target (lambda (radio) - (and (org-string-equal-ignore-case - (org-string-clean-whitespace (org-element-property :value radio)) + (and (string-equal-ignore-case + (string-clean-whitespace (org-element-property :value radio)) path) radio)) info 'first-match))) diff --git a/mk/default.mk b/mk/default.mk index 997b22b66..4ad1a4281 100644 --- a/mk/default.mk +++ b/mk/default.mk @@ -38,7 +38,7 @@ pkgdir = $(shell pwd)/pkg-deps EFLAGS ?= # Third-party packages to install when running make -EPACKAGES ?= +EPACKAGES ?= compat # Configuration for testing # Verbose ERT summary by default for Emacs-28 and above. diff --git a/testing/lisp/test-ol.el b/testing/lisp/test-ol.el index a38d9f979..565539571 100644 --- a/testing/lisp/test-ol.el +++ b/testing/lisp/test-ol.el @@ -63,19 +63,19 @@ (ert-deftest test-org-link/toggle-link-display () (dotimes (_ 2) (goto-char 1) (re-search-forward "\\[") - (should-not (org-xor org-link-descriptive (org-invisible-p))) + (should-not (xor org-link-descriptive (org-invisible-p))) (re-search-forward "example") - (should-not (org-xor org-link-descriptive (org-invisible-p))) + (should-not (xor org-link-descriptive (org-invisible-p))) (re-search-forward "com") - (should-not (org-xor org-link-descriptive (org-invisible-p))) + (should-not (xor org-link-descriptive (org-invisible-p))) (re-search-forward "]") - (should-not (org-xor org-link-descriptive (org-invisible-p))) + (should-not (xor org-link-descriptive (org-invisible-p))) (re-search-forward "\\[") (should-not (org-invisible-p)) (re-search-forward "link") (should-not (org-invisible-p)) (re-search-forward "]") - (should-not (org-xor org-link-descriptive (org-invisible-p))) + (should-not (xor org-link-descriptive (org-invisible-p))) (org-toggle-link-display))))) diff --git a/testing/lisp/test-org-capture.el b/testing/lisp/test-org-capture.el index 0ed44c6af..6a47b3384 100644 --- a/testing/lisp/test-org-capture.el +++ b/testing/lisp/test-org-capture.el @@ -154,7 +154,7 @@ (ert-deftest test-org-capture/abort () "Test aborting a capture process." ;; Newly create capture buffer should not be saved. (let ((capture-file (make-temp-name - (org-file-name-concat + (file-name-concat temporary-file-directory "org-test")))) (unwind-protect -- 2.39.1 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-org-manual.org-Document-compat-library-installation.patch >From 25047bc1d6c262aae7467723f12d0ed65c2f0e40 Mon Sep 17 00:00:00 2001 Message-Id: <25047bc1d6c262aae7467723f12d0ed65c2f0e40.1680454654.git.yantar92@posteo.net> In-Reply-To: References: From: Ihor Radchenko Date: Sat, 1 Apr 2023 12:18:57 +0200 Subject: [PATCH 3/6] org-manual.org: Document compat library installation * doc/org-manual.org (Using Org's git repository): Document that users must also install compat library when using git version of Org. * etc/ORG-NEWS (Org mode now uses =compat.el= third-party package to support older Emacs versions): Announce amendments to the Org installation from git sources. --- doc/org-manual.org | 4 ++++ etc/ORG-NEWS | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/doc/org-manual.org b/doc/org-manual.org index 50662669e..aa9886e5f 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -140,6 +140,10 @@ *** Using Org's git repository (add-to-list 'load-path "~/src/org-mode/lisp") #+end_src +You must also manually install =compat= library required by Org mode. +Using built-in =package.el=, you can run =M-x package-install +compat =. + You can also compile with =make=, generate the documentation with =make doc=, create a local configuration with =make config= and install Org with =make install=. Please run =make help= to get the diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index ac233a986..0302b8cda 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -13,6 +13,13 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org. * Version 9.7 (not released yet) ** Important announcements and breaking changes +*** Org mode now uses =compat.el= third-party package to support older Emacs versions + +This change is mostly technical and should not affect most users. +However, people who install Org from git source might be affected. +It is now necessary to manually install =compat.el= using Emacs' +package manager. + *** =python-mode.el (MELPA)= support in =ob-python.el= is removed =python-mode.el= support has been removed from =ob-python.el=. The -- 2.39.1 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0004-mk-Expand-shell-commands-once-only.patch >From 1515712e093137fe9642c7f1e2ebc0fc71119740 Mon Sep 17 00:00:00 2001 Message-Id: <1515712e093137fe9642c7f1e2ebc0fc71119740.1680454654.git.yantar92@posteo.net> In-Reply-To: References: From: Ihor Radchenko Date: Sun, 2 Apr 2023 13:53:47 +0200 Subject: [PATCH 4/6] mk: Expand shell commands once only * mk/default.mk (pkgdir): * mk/targets.mk (GITVERSION): (GITSTATUS): (DATE): (YEAR): Only expand the variables once, not in every make sub-process. Previous code ran pwd/date/git in every make sub-process, slowing things down significantly and unnecessarily. --- mk/default.mk | 2 +- mk/targets.mk | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mk/default.mk b/mk/default.mk index 4ad1a4281..b43a9b3ac 100644 --- a/mk/default.mk +++ b/mk/default.mk @@ -32,7 +32,7 @@ TMPDIR ?= /tmp testdir = $(TMPDIR)/tmp-orgtest # Where to store Org dependencies -pkgdir = $(shell pwd)/pkg-deps +pkgdir := $(shell pwd)/pkg-deps # Extra flags to be passed to Emacs EFLAGS ?= diff --git a/mk/targets.mk b/mk/targets.mk index ab8b830bb..18faa02f5 100644 --- a/mk/targets.mk +++ b/mk/targets.mk @@ -14,15 +14,15 @@ ifneq ($(wildcard .git),) # Use the org.el header. ORGVERSION := $(patsubst %-dev,%,$(shell $(BATCH) --eval "(require 'lisp-mnt)" \ --visit lisp/org.el --eval '(princ (lm-header "version"))')) - GITVERSION ?= $(shell git describe --match release\* --abbrev=6 HEAD 2>/dev/null || echo "release_N/A-N/A-$(shell git describe --match release\* --abbrev=6 --always HEAD)") - GITSTATUS ?= $(shell git status -uno --porcelain) + GITVERSION := $(shell git describe --match release\* --abbrev=6 HEAD 2>/dev/null || echo "release_N/A-N/A-$(shell git describe --match release\* --abbrev=6 --always HEAD)") + GITSTATUS := $(shell git status -uno --porcelain) else -include mk/version.mk GITVERSION ?= N/A ORGVERSION ?= N/A endif -DATE = $(shell date +%Y-%m-%d) -YEAR = $(shell date +%Y) +DATE := $(shell date +%Y-%m-%d) +YEAR := $(shell date +%Y) ifneq ($(GITSTATUS),) GITVERSION := $(GITVERSION:.dirty=).dirty endif -- 2.39.1 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0005-mk-Echo-main-compilation-states-when-running-make.patch >From 14140c127e5b44dd6f8aa76b5f6c946d77610939 Mon Sep 17 00:00:00 2001 Message-Id: <14140c127e5b44dd6f8aa76b5f6c946d77610939.1680454654.git.yantar92@posteo.net> In-Reply-To: References: From: Ihor Radchenko Date: Sun, 2 Apr 2023 14:05:22 +0200 Subject: [PATCH 5/6] mk: Echo main compilation states when running make * lisp/Makefile (all compile compile-dirty): ($(LISPV)): ($(LISPI)): Echo compile stage. * mk/targets.mk (uppkg): Echo compile stage and hide the installation command. --- lisp/Makefile | 7 +++++-- mk/targets.mk | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lisp/Makefile b/lisp/Makefile index f507f18a2..45d8109f0 100644 --- a/lisp/Makefile +++ b/lisp/Makefile @@ -20,6 +20,7 @@ _ORGCM_ := dirall single source slint1 slint2 # do not clean here, done in toplevel make all compile compile-dirty:: autoloads + @$(info ========= Compiling lisp files using '$(ORGCM)' target) ifeq ($(filter-out $(_ORGCM_),$(ORGCM)),) $(MAKE) compile-$(ORGCM) else @@ -52,12 +53,14 @@ slint1: autoloads: cleanauto $(LISPI) $(LISPV) $(LISPV): $(LISPF) - @echo "org-version: $(ORGVERSION) ($(GITVERSION))" + @$(info ========= Auto-generating Org version number) + @$(info org-version: $(ORGVERSION) ($(GITVERSION))) @$(RM) $(@) @$(MAKE_ORG_VERSION) $(LISPI): $(LISPV) $(LISPF) - @echo "org-loaddefs: $(ORGVERSION) ($(GITVERSION))" + @$(info ========= Auto-generating Org loaddefs) + @$(info org-loaddefs: $(ORGVERSION) ($(GITVERSION))) @$(RM) $(@) @$(MAKE_ORG_INSTALL) diff --git a/mk/targets.mk b/mk/targets.mk index 18faa02f5..072106237 100644 --- a/mk/targets.mk +++ b/mk/targets.mk @@ -103,9 +103,10 @@ ifeq ($(TEST_NO_AUTOCLEAN),) # define this variable to leave $(testdir) around f endif uppkg:: - -$(MKDIR) -p $(pkgdir) - -$(FIND) $(pkgdir) \( -name \*.elc \) -exec $(RM) {} + - $(INSTALL_PACKAGES) + $(info ========= Installing required third-party packages) + @$(MKDIR) -p $(pkgdir) + @$(FIND) $(pkgdir) \( -name \*.elc \) -exec $(RM) {} + + -@$(INSTALL_PACKAGES) up0 up1 up2:: git checkout $(GIT_BRANCH) -- 2.39.1 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0006-mk-Do-not-run-package-refresh-packages-unless-necess.patch >From dcb8bc6ba68834da94cef9006e6889c75e89f67a Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Ihor Radchenko Date: Sun, 2 Apr 2023 15:11:06 +0200 Subject: [PATCH 6/6] mk: Do not run `package-refresh-packages' unless necessary * mk/default.mk (package-install): (package-define-refresh-mark): (package-need-refresh-mark): (package-refresh-maybe): (package-install-maybe): (INSTALL_PACKAGES): Update the command avoiding `package-refresh-packages' when all the required third-party packages are already present in the `load-path'. --- mk/default.mk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mk/default.mk b/mk/default.mk index b43a9b3ac..67bf96c2e 100644 --- a/mk/default.mk +++ b/mk/default.mk @@ -81,7 +81,10 @@ REPRO_ARGS ?= req-ob-lang = --eval '(require '"'"'ob-$(ob-lang))' lst-ob-lang = ($(ob-lang) . t) req-extra = --eval '(require '"'"'$(req))' -package-install = --eval '(unless (require '"'"'$(package) nil t) (message "%s" load-path) (package-install '"'"'$(package)))' +package-define-refresh-mark = --eval '(setq org--compile-packages-missing nil)' +package-need-refresh-mark = --eval '(unless (require '"'"'$(package) nil t) (setq org--compile-packages-missing t))' +package-refresh-maybe = --eval '(if org--compile-packages-missing (package-refresh-contents) (message "No third-party packages need to be installed"))' +package-install-maybe = --eval '(unless (require '"'"'$(package) nil t) (package-install '"'"'$(package)))' BTEST_RE ?= \\(org\\|ob\\|ox\\) BTEST_LOAD = \ --eval '(add-to-list '"'"'load-path (concat default-directory "lisp"))' \ @@ -93,8 +96,8 @@ INSTALL_PACKAGES = else INSTALL_PACKAGES = \ $(BATCH) \ - --eval '(package-refresh-contents)' \ - $(foreach package,$(EPACKAGES),$(package-install)) + $(package-define-refresh-mark) $(foreach package,$(EPACKAGES),$(package-need-refresh-mark)) $(package-refresh-maybe) \ + $(foreach package,$(EPACKAGES),$(package-install-maybe)) endif BTEST = $(BATCH) $(BTEST_INIT) \ -- 2.39.1 --=-=-= Content-Type: text/plain -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at . Support Org development at , or support my work at --=-=-=--