[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/org-real a5736f1 070/160: Created buttons that link bac
From: |
ELPA Syncer |
Subject: |
[elpa] externals/org-real a5736f1 070/160: Created buttons that link back to the location of the link |
Date: |
Wed, 6 Oct 2021 16:58:17 -0400 (EDT) |
branch: externals/org-real
commit a5736f1295e4f8efad05243464ee97d3d82b2228
Author: Tyler Grinn <tylergrinn@gmail.com>
Commit: Tyler Grinn <tylergrinn@gmail.com>
Created buttons that link back to the location of the link
---
garage.org | 3 ++
org-real.el | 171 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 144 insertions(+), 30 deletions(-)
diff --git a/garage.org b/garage.org
index f4a4cdb..c6bee47 100644
--- a/garage.org
+++ b/garage.org
@@ -4,6 +4,9 @@
- [[real://garage/workbench?rel=in/nails?rel=on top of/screwdriver?rel=on
top of][screwdriver]]
- [[real://garage/workbench?rel=in/ratchet?rel=on top of][ratchet]]
- [[real://garage/east wall?rel=in/rake?rel=on/hoe?rel=to the left
of/snowblower?rel=above/shovel?rel=above][shovel]]
+ - [[real://garage/east wall?rel=in/rake?rel=on/hoe?rel=to the left
of/snowblower?rel=above/shovel?rel=above][shovel]]
+ - [[real://garage/east wall?rel=in/rake?rel=on/hoe?rel=to the left
of/snowblower?rel=above/shovel?rel=above][shovel]]
+ - [[real://garage/east wall?rel=in/rake?rel=on/hoe?rel=to the left
of/snowblower?rel=above/shovel?rel=above][shovel]]
- [[real://garage/east wall?rel=in/rake?rel=on][rake]]
- [[real://garage/workbench?rel=in/hammer?rel=on][hammer]]
- [[real://garage/east wall?rel=in/rake?rel=on/hoe?rel=to the left of][hoe]]
diff --git a/org-real.el b/org-real.el
index 3d7d208..2df511e 100644
--- a/org-real.el
+++ b/org-real.el
@@ -91,12 +91,16 @@
"Face for the last thing in a real link."
:group 'org-real)
-;;;; Constants
+;;;; Constants & variables
(defconst org-real-prepositions
'("in" "on" "behind" "in front of" "above" "below" "to the left of" "to the
right of" "on top of")
"List of available prepositions for things.")
+(defvar org-real--tab-ring '()
+ "List of buffer positions of buttons in an Org Real diagram.")
+(make-variable-buffer-local 'org-real--tab-ring)
+
;;;; Interactive functions
(defun org-real-world ()
@@ -109,6 +113,33 @@
(org-real--make-instance 'org-real-box containers))
(org-real--parse-buffer)))))
+;;;; Org Real mode
+
+(defun org-real-tab-cycle ()
+ "Cycle through buttons in the current Org Real buffer."
+ (interactive)
+ (if-let ((pos (seq-find (lambda (pos) (> pos (point))) org-real--tab-ring)))
+ (goto-char pos)))
+
+(defun org-real-tab-uncycle ()
+ "Cycle through buttons in the current Org Real buffer in reverse."
+ (interactive)
+ (if-let ((pos (seq-find (lambda (pos) (< pos (point))) (reverse
org-real--tab-ring))))
+ (goto-char pos)))
+
+(define-derived-mode org-real-mode special-mode
+ "Org Real"
+ "Mode for viewing an org-real diagram.
+
+The following commands are available:
+
+\\{org-real-mode-map}"
+ :group 'org-mode
+ (toggle-truncate-lines t))
+
+(define-key org-real-mode-map (kbd "TAB") 'org-real-tab-cycle)
+(define-key org-real-mode-map (kbd "<backtab>") 'org-real-tab-uncycle)
+
;;;; Pretty printing
(defun org-real--pp (box &optional containers)
@@ -122,17 +153,20 @@ describing where BOX is."
(inhibit-read-only t)
(buffer (get-buffer-create "Org Real")))
(with-current-buffer buffer
+ (org-real-mode)
(erase-buffer)
- (toggle-truncate-lines t)
+ (setq org-real--tab-ring '())
(if containers (org-real--pp-text containers))
(let ((offset (- (line-number-at-pos)
org-real-margin-y
(* 2 org-real-padding-y))))
(dotimes (_ (+ top height)) (insert (concat (make-string width ?\s)
"\n")))
(org-real--draw box offset)
- (special-mode)))
+ (goto-char 0)
+ (setq org-real--tab-ring
+ (seq-sort '< org-real--tab-ring))))
(display-buffer buffer `(display-buffer-pop-up-window
- (window-width . 80)
+ (window-width . ,width)
(window-height . ,height)))))
(defun org-real--pp-text (containers)
@@ -165,7 +199,7 @@ describing where BOX is."
(defun org-real-follow (url &rest _)
"Open a real link URL in a popup buffer."
- (let* ((containers (org-real--parse-url url))
+ (let* ((containers (org-real--parse-url url (point-marker)))
(box (org-real--make-instance 'org-real-box (copy-tree containers))))
(if org-real-include-context
(let* ((primary-name (plist-get (car (reverse containers)) :name))
@@ -188,7 +222,7 @@ describing where BOX is."
"Complete a real link or edit EXISTING link."
(let* ((container-matrix (org-real--parse-buffer))
(containers (if existing
- (org-real--parse-url existing)
+ (org-real--parse-url existing (point-marker))
(org-real--complete-thing "Thing: " container-matrix
'()))))
(catch 'confirm
(while t
@@ -284,7 +318,7 @@ ORIG is `org-insert-link', ARGS are the arguments passed to
it."
(setq new-link (org-unbracket-string "<" ">" (match-string 0)))))
(when (and new-link
(string= "real" (ignore-errors (url-type (url-generic-parse-url
new-link)))))
- (let ((new-containers (reverse (org-real--parse-url new-link))))
+ (let ((new-containers (reverse (org-real--parse-url new-link
(point-marker)))))
(while new-containers
(let ((primary (plist-get (car new-containers) :name))
(changes '())
@@ -293,7 +327,8 @@ ORIG is `org-insert-link', ARGS are the arguments passed to
it."
(lambda (old-link)
(when (string= (org-element-property :type old-link) "real")
(setq old-containers (reverse (org-real--parse-url
- (org-element-property
:raw-link old-link))))
+ (org-element-property
:raw-link old-link)
+ (set-marker (point-marker)
(org-element-property :begin old-link)))))
(when-let* ((new-index 0)
(old-index (seq-position
old-containers
@@ -396,7 +431,10 @@ ORIG is `org-insert-link', ARGS are the arguments passed
to it."
:type number)
(primary :initarg :primary
:initform nil
- :type boolean))
+ :type boolean)
+ (locations :initarg :locations
+ :initform '()
+ :type list))
"A representation of a box in 3D space.")
@@ -426,7 +464,8 @@ property and optionally a :rel property. If SKIP-PRIMARY is
non-nil, skip setting :primary slot on the last box."
(when-let* ((world (org-real-box))
(base-container (pop containers))
- (base (org-real-box :name (plist-get base-container :name))))
+ (base (org-real-box :name (plist-get base-container :name)
+ :locations (list (plist-get base-container
:loc)))))
(oset base :parent world)
(with-slots (children) world
(setq children (org-real--push children base)))
@@ -451,23 +490,34 @@ non-nil, skip setting :primary slot on the last box."
(cl-defmethod org-real--draw ((box org-real-box) offset)
"Insert an ascii drawing of BOX into the current buffer.
-OFFSET is the starting line to start insertion."
+OFFSET is the starting line to start insertion.
+
+Adds to list `org-real--tab-ring' the buffer position of each
+button drawn."
(let ((children (with-slots (children) box (org-real--get-all children))))
- (with-slots (name behind in-front on-top (dashed behind) primary) box
+ (with-slots (name behind in-front on-top (dashed behind) primary
locations) box
(when (slot-boundp box :name)
(let* ((top (+ offset (org-real--get-top box)))
(left (org-real--get-left box))
(width (org-real--get-width box))
(height (org-real--get-height box))
(align-bottom (or in-front on-top)))
- (cl-flet ((draw (coords str &optional primary)
- (forward-line (- (car coords) (line-number-at-pos)))
- (move-to-column (cdr coords) t)
- (if primary
- (put-text-property 0 (length str) 'face
'org-real-primary
- str))
- (insert str)
- (delete-char (length str))))
+ (cl-flet* ((draw (coords str)
+ (forward-line (- (car coords) (line-number-at-pos)))
+ (move-to-column (cdr coords) t)
+ (insert str)
+ (delete-char (length str)))
+ (button (coords str &optional primary)
+ (if (not locations) (draw coords str)
+ (forward-line (- (car coords)
(line-number-at-pos)))
+ (move-to-column (cdr coords) t)
+ (add-to-list 'org-real--tab-ring (point))
+ (if primary (put-text-property 0 (length str)
+ 'face
'org-real-primary str))
+ (insert-button str
+ 'help-echo "Jump to first
occurence"
+ 'keymap
(org-real--create-button-keymap box))
+ (delete-char (length str)))))
(draw (cons top left)
(concat "┌" (make-string (- width 2) (if dashed #x254c
#x2500)) "┐"))
(if align-bottom
@@ -475,7 +525,7 @@ OFFSET is the starting line to start insertion."
(concat "┴" (make-string (- width 2) (if dashed #x254c
#x2500)) "┴"))
(draw (cons (+ top height -1) left)
(concat "└" (make-string (- width 2) (if dashed #x254c
#x2500)) "┘")))
- (draw (cons (+ top 1 org-real-padding-y)
+ (button (cons (+ top 1 org-real-padding-y)
(+ left 1 org-real-padding-x))
name
primary)
@@ -683,9 +733,11 @@ If INCLUDE-ON-TOP is non-nil, also include height on top
of box."
PREV must already exist in PARENT."
(let* ((container (pop containers))
(rel (plist-get container :rel))
- (box (org-real-box :name (plist-get container :name))))
- (oset box :rel (plist-get container :rel))
- (oset box :rel-box prev)
+ (box (org-real-box
+ :name (plist-get container :name)
+ :rel (plist-get container :rel)
+ :rel-box prev
+ :locations (list (plist-get container :loc)))))
(with-slots
((cur-x x-order)
(cur-y y-order)
@@ -759,7 +811,7 @@ PREV must already exist in PARENT."
(setq cur-behind prev-behind)
(setq cur-on-top prev-on-top)
(setq cur-in-front prev-in-front)))
-
+
(if (and prev (member rel '("in" "on" "behind" "in front of" "on
top of")))
(progn
(oset box :parent prev)
@@ -838,6 +890,8 @@ MATCH is used to set the :rel-box and :parent slots on
relatives
of BOX."
(oset match :primary (or (with-slots (primary) match primary)
(with-slots (primary) box primary)))
+ (oset match :locations (append (with-slots (locations) match locations)
+ (with-slots (locations) box locations)))
(mapc
(lambda (next)
(org-real--add-matching-helper next match world))
@@ -982,6 +1036,61 @@ characters if possible."
(oset box :parent parent)
(setq siblings (org-real--push siblings box))))))
+;;;; Org real mode buttons
+
+(defun org-real--jump-other-window (markers)
+ "Jump to location of link in other window.
+
+MARKERS is a list of locations of each button in the buffer."
+ (let ((i 0))
+ (lambda ()
+ (interactive)
+ (let* ((marker (nth i markers))
+ (buffer (marker-buffer marker))
+ (pos (marker-position marker)))
+ (save-selected-window
+ (switch-to-buffer-other-window buffer)
+ (goto-char pos))
+ (setq i (mod (+ 1 i) (length markers)))))))
+
+(defun org-real--jump-to (marker)
+ "Jump to the first occurrence of a link in the same window.
+
+MARKER is the position of the first occurrence of the link."
+ (lambda ()
+ (interactive)
+ (switch-to-buffer (marker-buffer marker))
+ (goto-char (marker-position marker))))
+
+(defun org-real--jump-all (markers)
+ "View all occurrences of a link in the same window.
+
+MARKERS is the list of positions of the link."
+ (lambda ()
+ (interactive)
+ (let ((size (/ (window-height) (length markers))))
+ (or (<= window-min-height size)
+ (error "To many buffers to visit simultaneously"))
+ (switch-to-buffer (marker-buffer (car markers)))
+ (goto-char (marker-position (car markers)))
+ (dolist (marker (cdr markers))
+ (select-window (split-window nil size))
+ (switch-to-buffer (marker-buffer marker))
+ (goto-char (marker-position marker))))))
+
+(cl-defmethod org-real--create-button-keymap ((box org-real-box))
+ "Create a keymap for a button in Org Real mode.
+
+BOX is the box the button is being made for."
+ (with-slots (locations) box
+ (easy-mmode-define-keymap
+ (mapcar
+ (lambda (key) (cons (kbd (car key)) (cdr key)))
+ `(("o" . ,(org-real--jump-other-window locations))
+ ("<mouse-1>" . ,(org-real--jump-to (car locations)))
+ ("RET" . ,(org-real--jump-to (car locations)))
+ ("M-RET" . ,(org-real--jump-all locations)))))))
+
;;;; Utility expressions
(defun org-real--find-last-index (pred sequence)
@@ -1016,11 +1125,12 @@ LINK is escaped with backslashes for inclusion in
buffer."
(org-link-escape link)
(if description (format "[%s]" description) "")))))
-(defun org-real--parse-url (str)
+(defun org-real--parse-url (str marker)
"Parse STR into a list of plists.
Returns a list of plists with a :name property and optionally a
-:rel property."
+:rel property. MARKER is the location of the link and will be
+set to the :loc slot of each box."
(let* ((url (url-generic-parse-url str))
(host (url-host url))
(path-and-query (url-path-and-query url))
@@ -1031,14 +1141,14 @@ Returns a list of plists with a :name property and
optionally a
(containers (mapcar
(lambda (token)
(let* ((location (split-string token "\\?"))
- (container (list :name (car location)))
+ (container (list :name (car location) :loc
marker))
(rel (and (string-match "&?rel=\\([^&]*\\)"
(cadr location))
(match-string 1 (cadr location)))))
(if rel
(plist-put container :rel rel)
container)))
tokens)))
- (push (list :name host) containers)))
+ (push (list :name host :loc marker) containers)))
(defun org-real--parse-buffer ()
"Parse all real links in the current buffer."
@@ -1048,7 +1158,8 @@ Returns a list of plists with a :name property and
optionally a
(if (string= (org-element-property :type link) "real")
(add-to-list 'container-matrix
(org-real--parse-url
- (org-element-property :raw-link link))
+ (org-element-property :raw-link link)
+ (set-marker (point-marker) (org-element-property
:begin link)))
t))))
container-matrix))
- [elpa] externals/org-real 03234f7 059/160: Requirements before patches, (continued)
- [elpa] externals/org-real 03234f7 059/160: Requirements before patches, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 8550ace 004/160: Added alias "on" for "in", ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 72bf24b 007/160: Added documentation, ci/cd, and completion, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real c513e06 016/160: Updated readme, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 7f33978 027/160: Added apply function for rearranging other links, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 371024e 035/160: Satisfying ELC compiler, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 3e325b3 021/160: Simplified merge function, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real abb5aed 061/160: More edge cases, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 1160749 066/160: v0.2.0, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 256060a 064/160: Updated readme, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real a5736f1 070/160: Created buttons that link back to the location of the link,
ELPA Syncer <=
- [elpa] externals/org-real 4c81b19 071/160: org-real-headlines; Added more keys to Org Real mode, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real e46eb9c 075/160: Added ability to cycle children of a box, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 8ab3459 083/160: Added test framework, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real f6417b0 076/160: Added ability to collapse and expand boxes, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 92499a7 080/160: Updated readme, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 88c947d 088/160: # `org-real-headlines`, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real f74239f 089/160: Show diffs if test failed, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 881e4af 093/160: Merge branch 'next' into 'main', ELPA Syncer, 2021/10/06
- [elpa] externals/org-real 6a7fbe8 100/160: Added org mode keybindings suggestions, ELPA Syncer, 2021/10/06
- [elpa] externals/org-real ca52aef 110/160: Updated customizations; color scheme, ELPA Syncer, 2021/10/06