* Situation:
- Context: I have 2 org-contacts-files
- Bug: [[org-contact:]] link:
  - only works to the 1st file
  - cannot open link to 2nd file

* Reproduce with following:
** file /tmp/a.org
#+begin_src org :tangle /tmp/a.org
,* Person A-1
:PROPERTIES:
:NAME:     A-1
:EMAIL:     [email protected]
:END:

,* Person A-2
:PROPERTIES:
:NAME:     A-2
:EMAIL:     [email protected]
:END:
#+end_src

** file /tmp/b.org
#+begin_src org :tangle /tmp/b.org
,* Person B-1
:PROPERTIES:
:NAME:     B-1
:EMAIL:     [email protected]
:END:

,* Person B-2
:PROPERTIES:
:NAME:     B-2
:EMAIL:     [email protected]
:END:
#+end_src

** Setting org-contacts-files
#+begin_src emacs-lisp
(setq org-contacts-files '("/tmp/a.org" "/tmp/b.org"))
#+end_src

** Openning Links with org-open-at-point

- [[org-contact:Person A-2]] : working
- [[org-contact:Person B-2]] : NOT working

* Why I think the bug is happening:
The org-contacts-link-open function only using
(car (org-contacts-files)), ignores remainger.

#+begin_src emacs-lisp
(defun org-contacts-link-open (query)
  "Open org-contacts: link with jumping or searching QUERY."
  (let* ((file-path (car (org-contacts-files)))         <------ THIS LINE
----
         (file-name (file-name-nondirectory file-path))
          ...
#+end_src

* This patch fixes includes:
- Iterate over each file in 'org-contacts-files' and run the query against
each one.
- Replace 'occur' with 'multi-occur' so /query/ format searches are
performed on all files/buffers.
From 6936f4dd11d95dff8503ba739c65d903bce48351 Mon Sep 17 00:00:00 2001
From: garid_on_x13 <[email protected]>
Date: Fri, 20 Feb 2026 02:18:19 +0900
Subject: [PATCH 2/2] Fix org-contacts-link-open for multiple
 org-contacts-files scenarios.

---
 org-contacts.el | 57 +++++++++++++++++++++----------------------------
 1 file changed, 24 insertions(+), 33 deletions(-)

diff --git a/org-contacts.el b/org-contacts.el
index 1385390..7bf99a5 100644
--- a/org-contacts.el
+++ b/org-contacts.el
@@ -1648,39 +1648,30 @@ Each element has the form (NAME . (FILE . POSITION))."
 ;;;###autoload
 (defun org-contacts-link-open (query)
   "Open org-contacts: link with jumping or searching QUERY."
-  (let* ((file-path (car (org-contacts-files)))
-         (file-name (file-name-nondirectory file-path))
-         (buf (or (get-buffer file-name) (get-buffer (find-file-noselect file-path)))))
-    (cond
-     ;; /query/ format searching
-     ((string-match "/.*/" query)
-      (with-current-buffer buf
-        (string-match "/\\(.*\\)/" query)
-        (occur (match-string 1 query))))
-
-     ;; jump to exact contact headline directly
-     (t
-      (with-current-buffer buf
-        (if-let* ((marker (org-find-exact-headline-in-buffer query buf)))
-            (progn
-              (org-goto-marker-or-bmk marker)
-              (org-fold-show-context))
-          (user-error "[org-contacts] Can't find <%s> in your `org-contacts-files'" query)))
-      (display-buffer buf '(display-buffer-below-selected))
-
-      ;; FIXME:
-      ;; (let* ((contact-entry (map-filter
-      ;;                        (lambda (contact-plist)
-      ;;                          (if (string-equal (plist-get contact-plist :name) query)
-      ;;                              contact-plist))
-      ;;                        (org-contacts-all-contacts)))
-      ;;        (contact-name (plist-get contact-entry :name))
-      ;;        (file (plist-get contact-entry :file))
-      ;;        (position (plist-get contact-entry :position))
-      ;;        (buf (get-buffer (file-name-nondirectory file))))
-      ;;   (with-current-buffer buf (goto-char position))
-      ;;   (display-buffer buf '(display-buffer-below-selected)))
-      ))))
+  (let (( bufs (mapcar #'find-file-noselect (org-contacts-files)) )) ;; list of buffers of org-contacts-files
+    (cond ;;
+     ;; 1. /query/ format searching
+     ((string-match "/\\(.*\\)/" query)  ;; conditional check, as well as captures query
+      (multi-occur bufs                  ;; do 'occur' on all buffers of org-contacts-files
+       (match-string 1 query)))          ;; the captured query
+
+     ;; 2.  jump to exact contact headline directly
+     (t                                          ;;
+      (let ((query-has-found nil))               ;; local variable to check whether we found query
+        (dolist (buf bufs)                       ;; loop over all buffers
+          (unless query-has-found                ;; check query-has-found or not
+            (with-current-buffer buf
+              (if-let* ((marker (org-find-exact-headline-in-buffer query buf))) ;; check query
+                  (progn
+                    (org-link-open-as-file (buffer-file-name buf) nil) ;; added just for spliting windows better
+                    (org-goto-marker-or-bmk marker)
+                    (org-fold-show-context)
+                    (setq query-has-found t)     ;; sets query-has-found; thus it exits on loop
+                    )))))
+
+        (unless query-has-found         ;; notifies if there was no query
+          (user-error "[org-contacts] Can't find <%s> in your `org-contacts-files'" query))))
+     )))
 
 ;;;###autoload
 (defun org-contacts-link-complete (&optional _arg)
-- 
2.51.2

Reply via email to