emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/hyperdrive a1901daab3 05/82: WIP


From: ELPA Syncer
Subject: [nongnu] elpa/hyperdrive a1901daab3 05/82: WIP
Date: Mon, 25 Sep 2023 19:00:49 -0400 (EDT)

branch: elpa/hyperdrive
commit a1901daab32fd0d0f508626410dae23783be94fa
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>

    WIP
---
 DEV.org                  | 66 +++++++++++++++++++++++++++++++++++++
 tests/test-hyperdrive.el | 84 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/DEV.org b/DEV.org
index e3ec6f7b39..458c3d7bc5 100644
--- a/DEV.org
+++ b/DEV.org
@@ -277,3 +277,69 @@ even when that peer is not advertising the topic 
~not-advertising-this~.
 
 How to tell which extension caused a peer-open or peer-remove event?
 
+* Org links 
+
++ [[file:tests/org links.org][org links.org]]
+
+** Design
+
++ Basically, we want to always store a full ~hyper://...~ URL when the user 
calls ~org-store-link~.
++ Then, when the user calls ~org-insert-link~, we decide based on context (and 
maybe also on user input) what kind of a link to insert.
+
+*** Limitations
+
++ Because hyperdrive buffers are not considered file-backed by Emacs, and Org 
refuses to follow ~ID~-based links in non-file-backed buffers, in a 
hyperdrive-backed Org buffer, ~ID~-based links /will not/ be followable.  This 
is a limitation of ~org-id.el~, and it seems unlikely that we would be able to 
overcome it (unless and until we support hyperdrive using TRAMP's 
infrastructure).
+
+*** Use cases
+
++ We want users to be able to take one or more Org files and have links 
between them continue working regardless of whether the files are on a 
hyperdrive or not.
+
+*** Storing links
+
++ All examples below assume point is on a heading titled ~Heading A~.
+
+**** To a heading with a ~CUSTOM_ID~
+
+Assuming the ~CUSTOM_ID~ is ~heading-a~:
+
++ We'll follow Org's example by storing two links:
+  + ~hyper://public-key/foo.org#heading-a~
+  + ~hyper://public-key/foo.org#::*Heading A~
+
+**** To a heading with only an ~ID~
+
++ Because of the [[*Limitations][Limitations]], if the user stores a link to a 
heading that does not have a ~CUSTOM_ID~ but only has an ~ID~, we ignore the 
~ID~.
++ We store: ~hyper://public-key/foo.org#::*Heading A~
+
+**** To a heading with neither ~CUSTOM_ID~ nor ~ID~
+
++ We store: ~hyper://public-key/foo.org#::*Heading A~
+
+*** Inserting links
+
++ *NOTE:* Because of limitations in ~org-insert-link~, which is not 
extensible, we have come to the conclusion that our only feasible option for 
now is to copy its definition into hyperdrive.el and modify it slightly for 
hyperdrive-mode buffers; then we will use a /very/ simple advice around 
~org-insert-link~ to call our function in ~hyperdrive-mode~ buffers, falling 
back to the original function in all other cases.  If we are very careful with 
the advice function (and perhaps deactivate [...]
+
++ We first distinguish between whether the buffer we're inserting the link 
into is within the same hyperdrive, or not.
+
+**** Inserting into a buffer that is in the same hyperdrive
+
++ Like Org mode, we'll use a relative link.
+
+**** Inserting into a buffer that is not in the same hyperdrive
+
+**** Inserting full ~hyper://~ -prefixed links
+
++ These links may point only to files, or headings in files which have 
~CUSTOM_ID~ properties--not headings which have ~ID~ properties, nor by using 
~:search-option~-style heading matches.
++ Like in Org, a link using a ~#~-prefixed "fragment" may point only to a 
heading which has a ~CUSTOM_ID~ property; the ~ID~ property is not considered, 
nor is heading text.
+
++ This type of link may point to:
+  * A file (i.e. not to a heading within a file)
+  * A heading within a file, by:
+    * ~CUSTOM_ID~ (by placing the ID in the URL fragment, i.e. 
~hyper://.../foo.org#CUSTOM_ID~ )
+    * Heading text (by placing the Org search option in the URL fragment, 
URL-encoded, i.e. ~hyper://.../foo.org/#%3A%3A%2AHeading%20A~ to encode the 
search option ~::*Heading A~).
+    # TODO: Consider also supporting ~ID~ properties.
+
+**** Inserting relative links
+
++ 
+
diff --git a/tests/test-hyperdrive.el b/tests/test-hyperdrive.el
index 53e602f254..37b5794b06 100644
--- a/tests/test-hyperdrive.el
+++ b/tests/test-hyperdrive.el
@@ -36,6 +36,8 @@
 (require 'pcase)
 (require 'url)
 
+(require 'with-simulated-input)
+
 (require 'hyperdrive)
 
 ;;;; Magic constants
@@ -117,9 +119,11 @@
 
 ;;;; Link testing
 
+;;;;; Opening links
+
 (require 'hyperdrive-org)
 
-;;;;; URL links (i.e. "hyper://"-prefixed)
+;;;;;; URL links (i.e. "hyper://"-prefixed)
 
 (defun hyperdrive-test-org-url-link (url)
   "Return the URL that would be opened by `hyperdrive-open' for URL."
@@ -148,7 +152,7 @@
     (dolist (link links)
       (should (equal (hyperdrive-test-org-url-link (car link)) (cdr link))))))
 
-;;;;; Org links (i.e. not "hyper://"-prefixed)
+;;;;;; Org links (i.e. not "hyper://"-prefixed)
 
 (defun hyperdrive-test-org-link (link)
   ;; FIXME: Docstring.
@@ -175,3 +179,79 @@ LINK is an Org link as a string."
   (let ((links '(("[[*Heading A]]"))))
     (dolist (link links)
       (should (equal (hyperdrive-test-org-link (car link)) "WHAT")))))
+
+;;;;; Inserting links
+
+(defun hyperdrive-test-org-insert-link (link)
+  ;; FIXME: Docstring.
+  "Return the URL that would be inserted by `org-insert-link' for LINK.
+LINK is an Org link as a string."
+  (with-temp-buffer
+    (org-mode)
+    (hyperdrive-mode)
+    ;; TODO: Use org-link-store-props also?
+    (push link org-stored-links)
+    (org-insert-link)
+    (buffer-string)))
+
+(defun hyperdrive-test-org-link-roundtrip (contents)
+  (let ((org-id-link-to-org-use-id nil)
+        (default-directory "/")
+        (org-link-file-path-type
+         (lambda (path)
+           (replace-regexp-in-string (rx bos (optional "file:")
+                                         "/hyper:/") "hyper://" path)))
+        ;; (org-link-file-path-type
+        ;;  (lambda (path)
+        ;;    (string-trim-left (file-relative-name path)
+        ;;                      (rx "file:"))))
+        org-stored-links)
+    (with-temp-buffer
+      (insert contents)
+      (org-mode)
+      (hyperdrive-mode)
+      (setq-local hyperdrive-current-entry
+                  (hyperdrive-entry-create
+                   :hyperdrive (hyperdrive-create :public-key "public-key")
+                   :path "/foo/bar"))
+      (goto-char (point-min))
+      (re-search-forward (rx "<|>"))
+      (org-store-link nil 'interactive))
+    (with-temp-buffer
+      (org-mode)
+      (with-simulated-input "RET"
+        (org-insert-link))
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(hyperdrive-test-org-link-roundtrip
+ "<|>
+* Heading A
+* Heading B")
+"[[hyper://public-key/foo/bar]]"
+
+(hyperdrive-test-org-link-roundtrip
+ "* Heading A
+<|>
+* Heading B")
+"[[hyper://public-key/foo/bar#Heading%20A][Heading A]]"
+
+(hyperdrive-test-org-link-roundtrip
+ "* Heading A
+:PROPERTIES:
+:ID: deadbeef
+:END:
+<|>
+* Heading B")
+"[[hyper://public-key/foo/bar#deadbeef][Heading A]]"
+
+(hyperdrive-test-org-link-roundtrip
+ "* Heading A
+:PROPERTIES:
+:CUSTOM_ID: custom-id
+:END:
+<|>
+* Heading B")
+"[[hyper://public-key/foo/bar#custom-id][Heading A]]"
+
+
+"hyper://public-key/foo/bar#deadbeef"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]