From: Sergei Kosyrev <kosejin@proton.me>
To: emacs-orgmode@gnu.org
Subject: Re: [PATCH] org-id: implement arbitrary cross-file references
Date: Sat, 27 May 2023 15:19:57 +0000 [thread overview]
Message-ID: <tMZtldCSKDb6DImZOB74rM4a3KZrD9-Cf9_Kyq-z23MzoCub_pGdZowlkfN4RO0xzwPgDOS6t7gRpqfDiufb9UyiKdqB_5ybsWekjRHmJZE=@proton.me> (raw)
In-Reply-To: <sdvpm6lvq5s.fsf@netyu.xyz>
[-- Attachment #1: Type: text/plain, Size: 1080 bytes --]
On Saturday, May 27th, 2023 at 8:51 AM, Ruijie Yu via "General discussions about Org-mode." <emacs-orgmode@gnu.org> wrote:
> First of all, I believe this is not within the scope of TINYCHANGE,
> because as you see below, you added 58 lines and removed 11. In this
> case, the very first thing required before Org maintainers can consider
> its inclusion is that you sign the FSF copyright assignment. If you
> need more details, Ihor or Bastien could probably elaborate and/or send
> you the form.
Fair enough -- I'm open to sign the FSF copyright assignment.
> First, do we need to wrap it with `save-match-data'? In my personal code
> I almost always do, but I need a second opinion on that.
> Second, instead of the let-unless-null combination, you can just do this
> instead: (when-let ((match ...)) (let* (...) ...))
> And, if those values can't ever be nil, you could even combine the entirety
> of the` let*' form into the `when-let' form (and turn it into a` when-let*' form).
Thank you, all done, patch & GH PR updated.
--
regards,
Sergei Kosyrev
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-id-implement-arbitrary-cross-file-table-referenc.patch --]
[-- Type: text/x-patch; name=0001-org-id-implement-arbitrary-cross-file-table-referenc.patch, Size: 4990 bytes --]
From 960d864dd6587190a78353f27c2de10790560f31 Mon Sep 17 00:00:00 2001
From: Kosyrev Serge <serge.kosyrev@iohk.io>
Date: Thu, 25 May 2023 19:30:01 +0800
Subject: [PATCH] org-id: implement arbitrary cross-file table referencing
* Table formulae can now refer to data from tables in other files.
TINYCHANGE
---
etc/ORG-NEWS | 10 +++++++++
lisp/org-id.el | 57 ++++++++++++++++++++++++++++++++++++++---------
lisp/org-table.el | 2 +-
3 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 6b40198b5..311067628 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -221,6 +221,16 @@ Running shell blocks with the ~:session~ header freezes Emacs until
execution completes. The new ~:async~ header allows users to continue
editing with Emacs while a ~:session~ block executes.
+*** ~remote~ ~org-table~ can now refer to variables in other files
+
+Table formulae can now refer to data from tables in other files.
+
+Example:
+
+#+BEGIN_src org
+#+TBLFM: $2='(identity remote(file:./org-wile-with-tables.org,@@#$Value))
+#+END_src
+
** Miscellaneous
*** =org-crypt.el= now applies initial visibility settings to decrypted entries
diff --git a/lisp/org-id.el b/lisp/org-id.el
index aa9610f16..413babcd6 100644
--- a/lisp/org-id.el
+++ b/lisp/org-id.el
@@ -337,6 +337,40 @@ Move the cursor to that entry in that buffer."
(move-marker m nil)
(org-fold-show-context)))
+(defun org-id-parse-remote-table-ref (refstr)
+ (save-match-data
+ (when-let* ((match (string-match "^file:\\([^:]+\\)\\(\\|:.+\\)$" refstr))
+ (m1 (match-string 1 refstr))
+ (m2 (match-string 2 refstr))
+ (filename (cl-remove-if (lambda (c) (member c '(40 41)))
+ (org-table-formula-substitute-names m1)))
+ (table-name (org-table-formula-substitute-names m2)))
+ (list filename table-name))))
+
+(defun org-id-find-remote (file table-id markerp)
+ (if (file-exists-p file)
+ (let ((buffer (let ((query-about-changed-file nil))
+ (find-file-noselect file))))
+ (unwind-protect
+ (with-current-buffer buffer
+ (goto-char (point-min))
+ (let ((pos (progn
+ (unless (string= table-id "")
+ (let* ((ident (cl-subseq table-id 1))
+ (id-match (search-forward (concat "#+NAME: " ident) nil t)))
+ (unless id-match
+ (error "org-id-find-remote: file \"%s\" has no table with NAME \"%s\"." file ident))
+ (forward-line)))
+ (re-search-forward "^|-")
+ (move-beginning-of-line nil))))
+ (cond
+ ((null pos) nil)
+ (markerp (move-marker (make-marker) pos buffer))
+ (t (cons file pos)))))
+ ;; Remove opened buffer in the process.
+ (unless markerp (kill-buffer buffer))))
+ (error "org-id-find-remote: reference to missing file %s" file)))
+
;;;###autoload
(defun org-id-find (id &optional markerp)
"Return the location of the entry with the id ID.
@@ -346,16 +380,19 @@ With optional argument MARKERP, return the position as a new marker."
(cond
((symbolp id) (setq id (symbol-name id)))
((numberp id) (setq id (number-to-string id))))
- (let ((file (org-id-find-id-file id))
- org-agenda-new-buffers where)
- (when file
- (setq where (org-id-find-id-in-file id file markerp)))
- (unless where
- (org-id-update-id-locations nil t)
- (setq file (org-id-find-id-file id))
- (when file
- (setq where (org-id-find-id-in-file id file markerp))))
- where))
+ (let ((remote-match (org-id-parse-remote-table-ref id)))
+ (if remote-match
+ (org-id-find-remote (car remote-match) (cadr remote-match) markerp)
+ (let ((file (org-id-find-id-file id))
+ org-agenda-new-buffers where)
+ (when file
+ (setq where (org-id-find-id-in-file id file markerp)))
+ (unless where
+ (org-id-update-id-locations nil t)
+ (setq file (org-id-find-id-file id))
+ (when file
+ (setq where (org-id-find-id-in-file id file markerp))))
+ where))))
;;; Internal functions
diff --git a/lisp/org-table.el b/lisp/org-table.el
index ac685c41e..e894d563a 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -6281,7 +6281,7 @@ list of the fields in the rectangle."
(let ((case-fold-search t) (id-loc nil)
;; Protect a bunch of variables from being overwritten by
;; the context of the remote table.
- org-table-column-names org-table-column-name-regexp
+ org-table-column-names (org-table-column-name-regexp org-table-column-name-regexp)
org-table-local-parameters org-table-named-field-locations
org-table-current-line-types
org-table-current-begin-pos org-table-dlines
--
2.40.1
next prev parent reply other threads:[~2023-05-27 15:21 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-25 12:29 [PATCH] org-id: implement arbitrary cross-file references Sergei Kosyrev
2023-05-27 12:51 ` Sergei Kosyrev
2023-05-27 13:51 ` Ruijie Yu via General discussions about Org-mode.
2023-05-27 15:19 ` Sergei Kosyrev [this message]
2023-05-29 8:52 ` Ihor Radchenko
2023-07-02 10:58 ` Ihor Radchenko
2023-07-02 13:51 ` Sergei Kosyrev
2023-07-02 15:39 ` Ihor Radchenko
2023-10-02 13:36 ` Ihor Radchenko
2024-04-07 9:52 ` Ihor Radchenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='tMZtldCSKDb6DImZOB74rM4a3KZrD9-Cf9_Kyq-z23MzoCub_pGdZowlkfN4RO0xzwPgDOS6t7gRpqfDiufb9UyiKdqB_5ybsWekjRHmJZE=@proton.me' \
--to=kosejin@proton.me \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).