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

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

[elpa] externals/org-real da816c2 122/160: Merge branch 'next' into 'mai


From: ELPA Syncer
Subject: [elpa] externals/org-real da816c2 122/160: Merge branch 'next' into 'main'
Date: Wed, 6 Oct 2021 16:58:29 -0400 (EDT)

branch: externals/org-real
commit da816c28fc1d994c6933a9414a6d5b6a3d59c4a4
Merge: f80251e 58989c3
Author: Tyler Grinn <tyler@tygr.info>
Commit: Tyler Grinn <tyler@tygr.info>

    Merge branch 'next' into 'main'
    
    # Jump to location when entering org real mode
    
    With either org-real-world or org-real-headlines, org-real will try to find 
and jump to the matching box if point is in a link or a headline, respectively.
    
    # Reworked flexible layout
    flex-adjust no longer rearranges children, is faster.
    
    # Reworked cycle-down/up
    Now uses Cartesian distance to find the next box to jump to.
    
    See merge request tygrdev/org-real!7
---
 demo/garage.org |  30 +--
 org-real.el     | 670 +++++++++++++++++++++++++++++---------------------------
 2 files changed, 367 insertions(+), 333 deletions(-)

diff --git a/demo/garage.org b/demo/garage.org
index ae95ec8..9cef143 100644
--- a/demo/garage.org
+++ b/demo/garage.org
@@ -1,17 +1,17 @@
 * Items in the garage
-  - [[real://garage/workbench?rel=in][workbench]]
-  - [[real://garage/workbench?rel=in/paintbrush?rel=in front of][paintbrush]]
-  - [[real://garage/workbench?rel=in/paintbrush?rel=in front of/wrench?rel=to 
the left of][wrench]]
-  - [[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][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]]
-  - [[real://garage/car?rel=in/air freshener?rel=in][air freshener]]
-  - [[real://garage/workbench?rel=in/nails?rel=on top of][nails]]
-  - [[real://garage/east wall?rel=in][East wall]]
-  - [[real://garage/east wall?rel=in/rake?rel=on/hoe?rel=to the left 
of/snowblower?rel=above][snowblower]]
-  - [[real://garage/workbench?rel=in/hammer?rel=on/screws?rel=to the right 
of][screws]]
+  - [[real://garage/workbench][workbench]]
+  - [[real://garage/workbench/paintbrush?rel=in front of][paintbrush]]
+  - [[real://garage/workbench/paintbrush?rel=in front of/wrench?rel=to the 
left of][wrench]]
+  - [[real://garage/workbench/nails?rel=on top of/screwdriver?rel=on top 
of][screwdriver]]
+  - [[real://garage/workbench/ratchet?rel=on top of][ratchet]]
+  - [[real://garage/east wall/rake?rel=on/hoe?rel=to the left 
of/snowblower?rel=above/shovel?rel=above][shovel]]
+  - [[real://garage/east wall/rake?rel=on][rake]]
+  - [[real://garage/workbench/hammer?rel=on][hammer]]
+  - [[real://garage/east wall/rake?rel=on/hoe?rel=to the left of][hoe]]
+  - [[real://garage/car/air freshener][air freshener]]
+  - [[real://garage/workbench/nails?rel=on top of][nails]]
+  - [[real://garage/east wall][East wall]]
+  - [[real://garage/east wall/rake?rel=on/hoe?rel=to the left 
of/snowblower?rel=above][snowblower]]
+  - [[real://garage/workbench/hammer?rel=on/screws?rel=to the right 
of][screws]]
   - [[real://garage/saw?rel=on][saw]]
-  - [[real://garage/workbench?rel=in/paintbrush?rel=in front of/wrench?rel=to 
the left of/pliers?rel=below][pliers]]
+  - [[real://garage/workbench/paintbrush?rel=in front of/wrench?rel=to the 
left of/pliers?rel=below][pliers]]
diff --git a/org-real.el b/org-real.el
index 3f13785..b8c14f2 100644
--- a/org-real.el
+++ b/org-real.el
@@ -1,7 +1,7 @@
 ;;; org-real.el --- Keep track of real things as org-mode links -*- 
lexical-binding: t -*-
 
 ;; Author: Tyler Grinn <tylergrinn@gmail.com>
-;; Version: 0.4.0
+;; Version: 0.4.1
 ;; File: org-real.el
 ;; Package-Requires: ((emacs "26.1"))
 ;; Keywords: tools
@@ -212,106 +212,6 @@
   '("in" "on" "behind")
   "List of prepositions for which boxes are flexibly added to their parent.")
 
-;;;; Interactive functions
-
-(defun org-real-world ()
-  "View all real links in the current buffer."
-  (interactive)
-  (org-real--pp
-   (org-real--merge
-    (mapcar
-     (lambda (containers)
-       (org-real--make-instance 'org-real-box containers))
-     (org-real--parse-buffer)))
-   nil nil t))
-
-(defun org-real-headlines ()
-  "View all org headlines as an org real diagram.
-
-MAX-LEVEL is the maximum level to show headlines for."
-  (interactive)
-  (org-real--pp
-   (org-real--parse-headlines)
-   nil
-   'display-buffer-same-window
-   t 1 2))
-
-(defun org-real-apply ()
-  "Apply any change from the real link at point to the current buffer."
-  (interactive)
-  (let (new-link replace-all)
-    (cond
-     ((org-in-regexp org-link-bracket-re 1)
-      (setq new-link (match-string-no-properties 1)))
-     ((org-in-regexp org-link-plain-re)
-      (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 
(point-marker)))))
-        (while new-containers
-          (let ((primary (plist-get (car new-containers) :name))
-                (changes '())
-                old-containers)
-            (org-element-map (org-element-parse-buffer) 'link
-              (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)
-                                                 (set-marker (point-marker) 
(org-element-property :begin old-link)))))
-                  (when-let* ((new-index 0)
-                              (old-index (seq-position
-                                          old-containers
-                                          primary
-                                          (lambda (a b) (string= (plist-get a 
:name) b))))
-                              (begin (org-element-property :begin old-link))
-                              (end (org-element-property :end old-link))
-                              (replace-link (org-real--to-link
-                                             (reverse
-                                              (append (cl-subseq 
old-containers 0 old-index)
-                                                      new-containers)))))
-                    (when (catch 'conflict
-                            (if (not (= (length new-containers) (- (length 
old-containers) old-index)))
-                                (throw 'conflict t))
-                            (while (< new-index (length new-containers))
-                              (if (or (not (string= (plist-get (nth new-index 
new-containers) :name)
-                                                    (plist-get (nth old-index 
old-containers) :name)))
-                                      (not (string= (plist-get (nth new-index 
new-containers) :rel)
-                                                    (plist-get (nth old-index 
old-containers) :rel))))
-                                  (throw 'conflict t))
-                              (setq new-index (+ 1 new-index))
-                              (setq old-index (+ 1 old-index)))
-                            nil)
-                      (let* ((old-desc (save-excursion
-                                         (and (goto-char begin)
-                                              (org-in-regexp 
org-link-bracket-re 1)
-                                              (match-end 2)
-                                              (match-string-no-properties 2))))
-                             (new-link (org-real--link-make-string 
replace-link old-desc)))
-                        (push
-                         `(lambda ()
-                            (save-excursion
-                              (delete-region ,begin ,end)
-                              (goto-char ,begin)
-                              (insert ,new-link)))
-                         changes)))))))
-            (when (and changes
-                       (or replace-all (let ((response
-                                              (read-char-choice
-                                               (concat
-                                                "Replace all occurrences of "
-                                                primary
-                                                " in current buffer? y/n/a ")
-                                               '(?y ?Y ?n ?N ?a ?A)
-                                               t)))
-                                         (cond
-                                          ((or (= response ?y) (= response 
?Y)) t)
-                                          ((or (= response ?n) (= response 
?N)) nil)
-                                          ((or (= response ?a) (= response ?A))
-                                           (setq replace-all t))))))
-              (mapc 'funcall changes)))
-          (pop new-containers)))))
-  (message nil))
-
 ;;;; Org Real mode
 
 (defvar org-real--box-ring '()
@@ -353,36 +253,44 @@ MAX-LEVEL is the maximum level to show headlines for."
 (defun org-real-mode-cycle-down ()
   "Cycle to the next button on the row below."
   (interactive)
-  (let ((col (current-column)))
-    (forward-line 1)
-    (org-real-mode-cycle)
-    (move-to-column col)
-    (let ((pos (point)))
-      (goto-char (seq-reduce
-                  (lambda (closest p)
-                    (if (< (abs (- pos p))
-                           (abs (- pos closest)))
-                        p
-                      closest))
-                  org-real--box-ring
-                  1.0e+INF)))))
+  (let ((coords (cons (line-number-at-pos) (current-column))))
+    (goto-char (seq-reduce
+                (lambda (closest pos)
+                  (goto-char pos)
+                  (if (<= (line-number-at-pos) (car coords))
+                      closest
+                    (let* ((pos-coords (cons (line-number-at-pos) 
(current-column)))
+                           (pos-dist (sqrt (+ (expt (- (car pos-coords) (car 
coords)) 2)
+                                              (expt (- (cdr pos-coords) (cdr 
coords)) 2))))
+                           (closest-coords (and (goto-char closest) (cons 
(line-number-at-pos) (current-column))))
+                           (closest-dist (sqrt (+ (expt (- (car 
closest-coords) (car coords)) 2)
+                                                  (expt (- (cdr 
closest-coords) (cdr coords)) 2)))))
+                      (if (< pos-dist closest-dist)
+                          pos
+                        closest))))
+                org-real--box-ring
+                (point-max)))))
 
 (defun org-real-mode-cycle-up ()
   "Cycle to the next button on the row above."
   (interactive)
-  (let ((col (current-column)))
-    (forward-line -1)
-    (org-real-mode-uncycle)
-    (move-to-column col)
-    (let ((pos (point)))
-      (goto-char (seq-reduce
-                  (lambda (closest p)
-                    (if (< (abs (- pos p))
-                           (abs (- pos closest)))
-                        p
-                      closest))
-                  org-real--box-ring
-                  1.0e+INF)))))
+  (let ((coords (cons (line-number-at-pos) (current-column))))
+    (goto-char (seq-reduce
+                (lambda (closest pos)
+                  (goto-char pos)
+                  (if (>= (line-number-at-pos) (car coords))
+                      closest
+                    (let* ((pos-coords (cons (line-number-at-pos) 
(current-column)))
+                           (pos-dist (sqrt (+ (expt (- (car pos-coords) (car 
coords)) 2)
+                                              (expt (- (cdr pos-coords) (cdr 
coords)) 2))))
+                           (closest-coords (and (goto-char closest) (cons 
(line-number-at-pos) (current-column))))
+                           (closest-dist (sqrt (+ (expt (- (car 
closest-coords) (car coords)) 2)
+                                                  (expt (- (cdr 
closest-coords) (cdr coords)) 2)))))
+                      (if (< pos-dist closest-dist)
+                          pos
+                        closest))))
+                org-real--box-ring
+                (point-min)))))
 
 (defun org-real-mode-cycle-visibility ()
   "Cycle visibility on all children in the current buffer."
@@ -401,7 +309,7 @@ MAX-LEVEL is the maximum level to show headlines for."
 (defun org-real-mode-redraw ()
   "Redraw `org-real--current-box' in the current buffer."
   (org-real--make-dirty org-real--current-box)
-  (org-real--flex-adjust org-real--current-box)
+  (org-real--flex-adjust org-real--current-box org-real--current-box)
   (let ((inhibit-read-only t))
     (erase-buffer)
     (if org-real--current-containers
@@ -452,6 +360,136 @@ The following commands are available:
    ("n"         . org-real-mode-cycle-down)
    ("<backtab>" . org-real-mode-cycle-visibility)))
 
+;;;; Interactive functions
+
+(defun org-real-world ()
+  "View all real links in the current buffer."
+  (interactive)
+  (let ((link (cond
+               ((org-in-regexp org-link-bracket-re 1)
+                (match-string-no-properties 1))
+               ((org-in-regexp org-link-plain-re)
+                (org-unbracket-string "<" ">" (match-string 0)))))
+        (world (org-real--merge
+                (mapcar
+                 (lambda (containers)
+                   (org-real--make-instance 'org-real-box containers))
+                 (org-real--parse-buffer)))))
+    (org-real--pp world nil nil t)
+    (if (and link (string= "real" (ignore-errors (url-type 
(url-generic-parse-url link)))))
+        (let ((containers (reverse (org-real--parse-url link)))
+              match)
+          (while (and containers (or (not match) (not (org-real--is-visible 
match t))))
+            (setq match (org-real--find-matching
+                         (org-real-box :name (plist-get (pop containers) 
:name))
+                         world)))
+          (when match
+            (let ((top (org-real--get-top match))
+                  (left (org-real--get-left match)))
+              (run-with-timer
+               0 nil
+               (lambda ()
+                 (forward-line (- (+ org-real--current-offset top 1 
org-real-padding-y)
+                                  (line-number-at-pos)))
+                 (move-to-column (+ left 1 org-real-padding-x))))))))))
+
+(defun org-real-headlines ()
+  "View all org headlines as an org real diagram.
+
+MAX-LEVEL is the maximum level to show headlines for."
+  (interactive)
+  (let ((path (seq-filter 'identity (append (list (org-entry-get nil "ITEM")) 
(reverse (org-get-outline-path)))))
+        (world (save-excursion (org-real--parse-headlines)))
+        match)
+    (org-real--pp world nil 'display-buffer-same-window t 1 2)
+    (while (and path (or (not match) (not (org-real--is-visible match t))))
+      (setq match (org-real--find-matching (org-real-box :name (pop path)) 
world)))
+    (when match
+      (let ((top (org-real--get-top match))
+            (left (org-real--get-left match)))
+        (run-with-timer
+         0 nil
+         (lambda ()
+           (forward-line (- (+ org-real--current-offset top 1 
org-real-padding-y)
+                            (line-number-at-pos)))
+           (move-to-column (+ left 1 org-real-padding-x))))))))
+
+(defun org-real-apply ()
+  "Apply any change from the real link at point to the current buffer."
+  (interactive)
+  (let (new-link replace-all)
+    (cond
+     ((org-in-regexp org-link-bracket-re 1)
+      (setq new-link (match-string-no-properties 1)))
+     ((org-in-regexp org-link-plain-re)
+      (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 
(point-marker)))))
+        (while new-containers
+          (let ((primary (plist-get (car new-containers) :name))
+                (changes '())
+                old-containers)
+            (org-element-map (org-element-parse-buffer) 'link
+              (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)
+                                                 (set-marker (point-marker) 
(org-element-property :begin old-link)))))
+                  (when-let* ((new-index 0)
+                              (old-index (seq-position
+                                          old-containers
+                                          primary
+                                          (lambda (a b) (string= (plist-get a 
:name) b))))
+                              (begin (org-element-property :begin old-link))
+                              (end (org-element-property :end old-link))
+                              (replace-link (org-real--to-link
+                                             (reverse
+                                              (append (cl-subseq 
old-containers 0 old-index)
+                                                      new-containers)))))
+                    (when (catch 'conflict
+                            (if (not (= (length new-containers) (- (length 
old-containers) old-index)))
+                                (throw 'conflict t))
+                            (while (< new-index (length new-containers))
+                              (if (or (not (string= (plist-get (nth new-index 
new-containers) :name)
+                                                    (plist-get (nth old-index 
old-containers) :name)))
+                                      (not (string= (plist-get (nth new-index 
new-containers) :rel)
+                                                    (plist-get (nth old-index 
old-containers) :rel))))
+                                  (throw 'conflict t))
+                              (setq new-index (+ 1 new-index))
+                              (setq old-index (+ 1 old-index)))
+                            nil)
+                      (let* ((old-desc (save-excursion
+                                         (and (goto-char begin)
+                                              (org-in-regexp 
org-link-bracket-re 1)
+                                              (match-end 2)
+                                              (match-string-no-properties 2))))
+                             (new-link (org-real--link-make-string 
replace-link old-desc)))
+                        (push
+                         `(lambda ()
+                            (save-excursion
+                              (delete-region ,begin ,end)
+                              (goto-char ,begin)
+                              (insert ,new-link)))
+                         changes)))))))
+            (when (and changes
+                       (or replace-all (let ((response
+                                              (read-char-choice
+                                               (concat
+                                                "Replace all occurrences of "
+                                                primary
+                                                " in current buffer? y/n/a ")
+                                               '(?y ?Y ?n ?N ?a ?A)
+                                               t)))
+                                         (cond
+                                          ((or (= response ?y) (= response 
?Y)) t)
+                                          ((or (= response ?n) (= response 
?N)) nil)
+                                          ((or (= response ?a) (= response ?A))
+                                           (setq replace-all t))))))
+              (mapc 'funcall changes)))
+          (pop new-containers)))))
+  (message nil))
+
 ;;;; Pretty printing
 
 (defun org-real--pp (box
@@ -674,6 +712,10 @@ ORIG is `org-insert-link', ARGS are the arguments passed 
to it."
              :type string)
    (rel-box :initarg :rel-box
             :type org-real-box)
+   (display-rel :initarg :display-rel
+                :type string)
+   (display-rel-box :initarg :display-rel-box
+                    :type org-real-box)
    (x-order :initarg :x-order
             :initform 0
             :type number)
@@ -783,8 +825,11 @@ non-nil, skip setting :primary slot on the last box."
       (let ((all-from-children (org-real--get-children from 'all)))
         (with-slots ((to-children children) (to-behind behind)) to
           (if (= 1 (length all-from-children))
-              (org-real--flex-add (car all-from-children) to)
-            (org-real--flex-add from to)))))))
+              (progn
+                (oset (car all-from-children) :flex t)
+                (org-real--add-child to (car all-from-children)))
+            (oset from :flex t)
+            (org-real--add-child to from)))))))
 
 (cl-defmethod org-real--update-visibility ((box org-real-box))
   "Update visibility of BOX and all of its children."
@@ -1130,7 +1175,7 @@ If INCLUDE-ON-TOP is non-nil, also include height on top 
of box."
 
 (cl-defmethod org-real--create-cursor-function ((box org-real-box))
   "Create cursor functions for entering and leaving BOX."
-  (with-slots (rel rel-box name metadata) box
+  (with-slots (rel rel-box display-rel-box display-rel name metadata) box
     (let (tooltip-timer)
       (lambda (_window _oldpos dir)
         (let ((inhibit-read-only t))
@@ -1140,17 +1185,27 @@ If INCLUDE-ON-TOP is non-nil, also include height on 
top of box."
                   (if (slot-boundp box :metadata)
                       (setq tooltip-timer (org-real--tooltip metadata))
                     (if (and (slot-boundp box :name) (slot-boundp box :rel))
-                        (with-slots ((rel-name name)) rel-box
+                        (with-slots ((rel-name name)) (if (slot-boundp box 
:display-rel-box)
+                                                          display-rel-box
+                                                        rel-box)
                           (setq tooltip-timer
                                 (org-real--tooltip
                                  (with-temp-buffer
                                    (insert (format "The %s is %s the %s."
-                                                   name rel rel-name))
+                                                   name
+                                                   (if (slot-boundp box 
:display-rel)
+                                                       display-rel
+                                                     rel)
+                                                   rel-name))
                                    (let ((fill-column 
org-real-tooltip-max-width))
                                      (fill-paragraph t))
                                    (buffer-string)))))))
-                  (if (slot-boundp box :rel-box)
-                      (org-real--draw rel-box 'rel))
+                  (if (slot-boundp box :display-rel-box)
+                      (if (org-real--is-visible display-rel-box t)
+                          (org-real--draw display-rel-box 'rel))
+                    (if (and (slot-boundp box :rel-box)
+                             (org-real--is-visible rel-box t))
+                        (org-real--draw rel-box 'rel)))
                   (org-real--draw box 'selected))
               (if tooltip-timer (cancel-timer tooltip-timer))
               (if (slot-boundp box :rel-box)
@@ -1231,11 +1286,18 @@ BOX is the box the button is being made for."
 
 ;;;; Private class methods
 
-(cl-defmethod org-real--is-visible ((box org-real-box))
-  "Determine if BOX is visible according to `org-real--visibility'."
-  (with-slots (level) box
-    (or (= 0 org-real--visibility)
-        (<= level org-real--visibility))))
+(cl-defmethod org-real--is-visible ((box org-real-box) &optional calculate)
+  "Determine if BOX is visible according to `org-real--visibility'.
+
+If CALCULATE, determine if the box has been expanded manually."
+  (if calculate
+      (with-slots (parent) box
+        (seq-find
+         (lambda (sibling) (eq sibling box))
+         (org-real--get-children parent)))
+    (with-slots (level) box
+      (or (= 0 org-real--visibility)
+          (<= level org-real--visibility)))))
 
 (cl-defmethod org-real--get-children ((box org-real-box) &optional arg)
   "Get all visible children of BOX.
@@ -1261,9 +1323,14 @@ If optional ARG is 'hidden, only return hidden children"
 If FORCE-VISIBLE, always make CHILD visible in PARENT."
   (oset child :parent parent)
   (with-slots (children hidden-children) parent
-    (if (or force-visible (org-real--is-visible child))
-        (setq children (org-real--push children child))
-      (setq hidden-children (org-real--push hidden-children child)))))
+    (if (org-real--get-all hidden-children)
+        (progn
+          (setq hidden-children (org-real--push hidden-children child))
+          (if (or force-visible (org-real--is-visible child))
+              (cl-rotatef children hidden-children)))
+      (if (or force-visible (org-real--is-visible child))
+          (setq children (org-real--push children child))
+        (setq hidden-children (org-real--push hidden-children child))))))
 
 (cl-defmethod org-real--get-world ((box org-real-box))
   "Get the top most box related to BOX."
@@ -1331,88 +1398,62 @@ PREV must already exist in PARENT."
                :name (plist-get container :name)
                :locations (list (plist-get container :loc)))))
     (with-slots
-        ((cur-x x-order)
-         (cur-y y-order)
-         (cur-level level)
+        ((cur-level level)
          (cur-behind behind)
          (cur-on-top on-top)
-         (cur-in-front in-front))
+         (cur-in-front in-front)
+         display-rel
+         display-rel-box
+         flex)
         box
         (with-slots
-            ((prev-x x-order)
-             (prev-y y-order)
-             (prev-level level)
+            ((prev-level level)
              (prev-behind behind)
              (prev-on-top on-top)
              (prev-in-front in-front))
             prev
           (cond
            ((or (string= rel "in") (string= rel "on"))
+            (setq flex t)
             (setq cur-level (+ 1 prev-level))
             (setq cur-behind prev-behind))
            ((string= rel "behind")
+            (setq flex t)
             (setq cur-level (+ 1 prev-level))
             (setq cur-behind t))
            ((string= rel "in front of")
             (setq cur-level (+ 1 prev-level))
-            (setq cur-y 1.0e+INF)
             (setq cur-behind prev-behind)
             (setq cur-in-front t))
            ((string= rel "on top of")
             (setq cur-level (+ 1 prev-level))
-            (setq cur-y -1.0e+INF)
             (setq cur-behind prev-behind)
             (setq cur-on-top t))
            ((member rel '("above" "below"))
             (setq cur-behind prev-behind)
-            (setq cur-x prev-x)
             (cond
              ((and prev-in-front (string= rel "below"))
+              (setq display-rel-box prev)
               (while (with-slots (in-front) prev in-front)
                 (setq prev (with-slots (parent) prev parent)))
               (setq parent (with-slots (parent) prev parent)))
              ((and prev-on-top (string= rel "above"))
+              (setq display-rel-box prev)
               (while (with-slots (on-top) prev on-top)
                 (setq prev (with-slots (parent) prev parent)))
               (setq parent (with-slots (parent) prev parent)))
              ((and prev-on-top (string= rel "below"))
+              (setq display-rel rel)
+              (setq display-rel-box prev)
               (setq rel "in")
-              (setq prev parent)))
-            (setq cur-level (+ 1 (with-slots (level) parent level)))
-            (let ((sibling-y-orders
-                   (mapcar
-                    (lambda (sibling) (with-slots (y-order) sibling y-order))
-                    (seq-filter
-                     (lambda (sibling)
-                       (with-slots (in-front on-top) sibling
-                         (not (or in-front on-top))))
-                     (org-real--get-children parent 'all)))))
-              (if (or prev-on-top (string= rel "above"))
-                  (setq cur-y (- (apply 'min 0 sibling-y-orders) 1))
-                (setq cur-y (+ 1 (apply 'max 0 sibling-y-orders))))))
+              (setq prev parent))))
            ((member rel '("to the left of" "to the right of"))
             (setq cur-level prev-level)
-            (setq cur-y prev-y)
             (setq cur-behind prev-behind)
             (setq cur-on-top prev-on-top)
-            (setq cur-in-front prev-in-front)
-            (if (string= rel "to the left of")
-                (setq cur-x prev-x)
-              (setq cur-x (+ 1 prev-x)))
-            (let ((row-siblings (seq-filter
-                                 (lambda (sibling)
-                                   (with-slots (y-order) sibling
-                                     (= prev-y y-order)))
-                                 (org-real--get-children parent 'all))))
-              (mapc
-               (lambda (sibling)
-                 (with-slots (x-order) sibling
-                   (if (>= x-order cur-x)
-                       (setq x-order (+ 1 x-order)))))
-               row-siblings))))
+            (setq cur-in-front prev-in-front)))
           (oset box :rel rel)
           (oset box :rel-box prev)
-          (if (not (slot-boundp box :name)) (setq cur-level 0))
           (if (member rel org-real-children-prepositions)
               (progn
                 (org-real--add-child prev box)
@@ -1447,19 +1488,20 @@ PREV must already exist in PARENT."
 
 (cl-defmethod org-real--add-next ((next org-real-box)
                                   (prev org-real-box)
-                                  &optional force-visible)
+                                  &optional force-visible skip-next)
   "Add NEXT to world according to its relationship to PREV.
 
 If FORCE-VISIBLE, show the box regardless of
-`org-real--visibility'."
+`org-real--visibility'
+
+If SKIP-NEXT, don't add expansion slots for boxes related to
+NEXT."
   (with-slots
       (children
        hidden-children
        parent
        (prev-level level)
        (prev-primary primary)
-       (prev-y y-order)
-       (prev-x x-order)
        (prev-behind behind)
        (prev-in-front in-front)
        (prev-on-top on-top))
@@ -1468,9 +1510,8 @@ If FORCE-VISIBLE, show the box regardless of
         (rel
          rel-box
          extra-data
+         flex
          (next-level level)
-         (next-y y-order)
-         (next-x x-order)
          (next-behind behind)
          (next-in-front in-front)
          (next-on-top on-top))
@@ -1494,82 +1535,100 @@ If FORCE-VISIBLE, show the box regardless of
           (cond
            ((member rel '("to the left of" "to the right of"))
             (setq next-level prev-level)
-            (setq next-y prev-y)
             (setq next-behind prev-behind)
             (setq next-in-front prev-in-front)
-            (setq next-on-top prev-on-top)
-            (if (string= rel "to the left of")
-                (setq next-x prev-x)
-              (setq next-x (+ 1 prev-x)))
-            (let ((row-siblings (seq-filter
-                                 (lambda (sibling)
-                                   (with-slots (y-order) sibling
-                                     (= y-order prev-y)))
-                                 (org-real--get-children parent 'all))))
-              (mapc
-               (lambda (sibling)
-                 (with-slots (x-order) sibling
-                   (if (>= x-order next-x)
-                       (setq x-order (+ 1 x-order)))))
-               row-siblings)))
+            (setq next-on-top prev-on-top))
            ((member rel '("above" "below"))
             (setq next-level prev-level)
-            (setq next-x prev-x)
-            (setq next-behind prev-behind)
-            (let ((sibling-y-orders (mapcar
-                                     (lambda (sibling) (with-slots (y-order) 
sibling y-order))
-                                     (seq-filter
-                                      (lambda (sibling)
-                                        (with-slots (in-front on-top) sibling
-                                          (not (or in-front on-top))))
-                                      (org-real--get-children parent 'all)))))
-              (if (string= rel "above")
-                  (setq next-y (- (apply 'min 0 sibling-y-orders) 1))
-                (setq next-y (+ 1 (apply 'max 0 sibling-y-orders))))))
+            (setq next-behind prev-behind))
            ((or next-on-top next-in-front)
             (setq next-level (+ 1 prev-level))
-            (setq next-x (+ 1 (apply 'max 0
-                                     (mapcar
-                                      (lambda (child) (with-slots (x-order) 
child x-order))
-                                      (seq-filter
-                                       (lambda (child)
-                                         (with-slots (in-front on-top) child
-                                           (and (eq next-in-front in-front)
-                                                (eq next-on-top on-top))))
-                                       (org-real--get-children prev 'all))))))
             (setq next-behind prev-behind))
            ((member rel '("in" "on" "behind"))
+            (setq flex t)
+            (setq next-level (+ 1 prev-level)))
+           ((string= rel "behind")
+            (setq flex t)
             (setq next-level (+ 1 prev-level))
-            (setq next-behind prev-behind)))
-          (if (not (slot-boundp next :name)) (setq next-level 0))
+            (setq next-behind t)))
           (oset next :rel-box prev)
           (if (member rel org-real-children-prepositions)
-              (if (member rel org-real-flex-prepositions)
-                  (org-real--flex-add next prev)
-                (org-real--add-child prev next force-visible))
+              (org-real--add-child prev next force-visible)
             (org-real--add-child parent next force-visible))
-          (if children-boxes
-              (oset next :expand-children
-                    '(lambda (box)
-                       (mapc
-                        (lambda (child) (org-real--add-next child box))
-                        (alist-get 'children (oref box :extra-data))))))
-          (if sibling-boxes
-              (oset next :expand-siblings
-                    '(lambda (box)
-                       (mapc
-                        (lambda (sibling) (org-real--add-next sibling box t))
-                        (alist-get 'siblings (oref box :extra-data)))))))))))
+          (unless skip-next
+            (if children-boxes
+                (oset next :expand-children
+                      '(lambda (box)
+                         (mapc
+                          (lambda (child) (org-real--add-next child box))
+                          (alist-get 'children (oref box :extra-data))))))
+            (if sibling-boxes
+                (oset next :expand-siblings
+                      '(lambda (box)
+                         (mapc
+                          (lambda (sibling) (org-real--add-next sibling box t))
+                          (alist-get 'siblings (oref box 
:extra-data))))))))))))
+
+(cl-defmethod org-real--position-box ((box org-real-box))
+  "Adjust BOX's position."
+  (with-slots (rel-box rel parent x-order y-order on-top in-front parent) box
+    (with-slots ((rel-y y-order) (rel-x x-order)) rel-box
+      (unless (org-real--find-matching box rel-box)
+        (if on-top
+            (setq y-order -1.0e+INF))
+        (if in-front
+            (setq y-order 1.0e+INF))
+        (cond
+         ((member rel '("to the left of" "to the right of"))
+          (setq y-order rel-y)
+          (if (string= rel "to the left of")
+              (setq x-order rel-x)
+            (setq x-order (+ 1 rel-x)))
+          (let ((row-siblings (seq-filter
+                               (lambda (sibling)
+                                 (with-slots ((sibling-y y-order)) sibling
+                                   (= sibling-y rel-y)))
+                               (org-real--get-children parent 'all))))
+            (mapc
+             (lambda (sibling)
+               (with-slots ((sibling-x x-order)) sibling
+                 (if (>= sibling-x x-order)
+                     (setq sibling-x (+ 1 sibling-x)))))
+             row-siblings)))
+         ((member rel '("above" "below"))
+          (setq x-order rel-x)
+          (let ((sibling-y-orders (mapcar
+                                   (lambda (sibling) (with-slots (y-order) 
sibling y-order))
+                                   (seq-filter
+                                    (lambda (sibling)
+                                      (with-slots (in-front on-top) sibling
+                                        (not (or in-front on-top))))
+                                    (org-real--get-children parent 'all)))))
+            (if (string= rel "above")
+                (setq y-order (- (apply 'min 0 sibling-y-orders) 1))
+              (setq y-order (+ 1 (apply 'max 0 sibling-y-orders))))))
+         ((or on-top in-front)
+          (setq x-order (+ 1 (apply 'max 0
+                                    (mapcar
+                                     (lambda (child) (with-slots (x-order) 
child x-order))
+                                     (seq-filter
+                                      (lambda (child)
+                                        (with-slots ((child-in-front in-front) 
(child-on-top on-top)) child
+                                           (and (eq in-front child-in-front)
+                                                (eq on-top child-on-top))))
+                                      (org-real--get-children rel-box 
'all))))))))
+        (org-real--add-child parent box t)))))
+
 
 (cl-defmethod org-real--flex-add ((box org-real-box)
-                                  (parent org-real-box))
+                                  (parent org-real-box)
+                                  (world org-real-box))
   "Add BOX to a PARENT box flexibly.
 
 This function ignores the :rel slot and adds BOX in such a way
-that the width of the world is kept below `org-real-flex-width'
+that the width of the WORLD is kept below `org-real-flex-width'
 characters if possible."
-  (let* ((world (org-real--get-world parent))
-         (cur-width (org-real--get-width world)))
+  (let ((cur-width (org-real--get-width world)))
     (org-real--make-dirty world)
     (with-slots ((parent-level level) (parent-behind behind)) parent
       (let* ((level (+ 1 parent-level))
@@ -1577,7 +1636,7 @@ characters if possible."
                             (lambda (sibling)
                               (with-slots (in-front on-top) sibling
                                 (not (or in-front on-top))))
-                            (org-real--get-children parent 'all)))
+                            (org-real--get-children parent)))
              (last-sibling (and all-siblings
                                 (seq-reduce
                                  (lambda (max sibling)
@@ -1593,7 +1652,8 @@ characters if possible."
         (oset box :flex t)
         (oset box :behind parent-behind)
         (org-real--apply-level box level)
-        (org-real--add-child parent box)
+        (org-real--add-child parent box t)
+        (org-real--flex-adjust box world)
         (when last-sibling
           (with-slots
               ((last-sibling-y y-order)
@@ -1605,70 +1665,46 @@ characters if possible."
               (org-real--make-dirty world)
               (when (and (> new-width cur-width) (> new-width 
org-real-flex-width))
                 (oset box :y-order (+ 1 last-sibling-y))
-                (oset box :x-order 0)))))))))
-
-(cl-defmethod org-real--flex-adjust ((box org-real-box))
-  "Adjust BOX x and y orders to try to fit BOX within `org-real-flex-width'."
-  (let ((cur-width (org-real--get-width box))
-        new-width)
-    (org-real--flex-adjust-helper box box)
-    (setq new-width (org-real--get-width box))
-    (while (and (< new-width cur-width)
-                (> new-width org-real-flex-width))
-      (setq cur-width new-width)
-      (org-real--flex-adjust-helper box box)
-      (setq new-width (org-real--get-width box)))))
-
-(cl-defmethod org-real--flex-adjust-helper ((box org-real-box) (world 
org-real-box))
+                (oset box :x-order 0)
+                (org-real--flex-adjust box world)))))))))
+
+(cl-defmethod org-real--partition (fn (collection org-real-box-collection))
+  "Partition COLLECTION into two collections using predicate FN."
+  (if (not (slot-boundp collection :box))
+      (list (org-real-box-collection) (org-real-box-collection))
+    (let ((pass (org-real-box-collection))
+          (fail (org-real-box-collection)))
+      (while (slot-boundp collection :box)
+        (with-slots (box next) collection
+          (if (funcall fn box)
+              (setq pass (org-real--push pass box))
+            (setq fail (org-real--push fail box)))
+          (if (slot-boundp collection :next)
+              (setq collection next)
+            (setq collection (org-real-box-collection)))))
+      (list pass fail))))
+
+(cl-defmethod org-real--flex-adjust ((box org-real-box) (world org-real-box))
   "Adjust BOX x and y orders to try to fit WORLD within `org-real-flex-width'."
-  (with-slots (flex parent) box
-    (when flex
-      (let ((cur-width (org-real--get-width world)))
-        (when (> cur-width org-real-flex-width)
-          (let ((left (org-real--get-left box))
-                (width (org-real--get-width box)))
-            (when (> (+ left width) org-real-flex-width)
-              (org-real--make-dirty world)
-              (when-let* ((all-siblings (seq-filter
-                                         (lambda (sibling)
-                                           (with-slots (in-front on-top) 
sibling
-                                             (not (or in-front on-top))))
-                                         (org-real--get-children parent)))
-                          (last-sibling (seq-reduce
-                                         (lambda (max sibling)
-                                           (with-slots ((max-x x-order) (max-y 
y-order)) max
-                                             (with-slots
-                                                 ((sibling-x x-order)
-                                                  (sibling-y y-order))
-                                                 sibling
-                                               (if (> sibling-y max-y)
-                                                   sibling
-                                                 (if (and (= max-y sibling-y) 
(> sibling-x max-x))
-                                                     sibling
-                                                   max)))))
-                                         all-siblings
-                                         (org-real-box :y-order -1.0e+INF))))
-                (with-slots
-                    ((last-sibling-y y-order)
-                     (last-sibling-x x-order))
-                    last-sibling
-                  (oset box :y-order last-sibling-y)
-                  (oset box :x-order (+ 1 last-sibling-x))
-                  (let ((when-last (org-real--get-width world)))
-                    (when (> when-last org-real-flex-width)
-                      (org-real--make-dirty world)
-                      (oset box :y-order (+ 1 last-sibling-y))
-                      (oset box :x-order 0)
-                      (let ((when-new-row (org-real--get-width world)))
-                        (when (>= when-new-row when-last)
-                          (org-real--make-dirty world)
-                          (oset box :y-order last-sibling-y)
-                          (oset box :x-order (+ 1 last-sibling-x))))))))))))))
-  (mapc
-   (lambda (child)
-     (org-real--flex-adjust-helper child world))
-   (org-real--get-children box)))
-
+  (with-slots (children) box
+    (let* ((partitioned (org-real--partition
+                         (lambda (child) (with-slots (flex) child flex))
+                         children))
+           (flex-children (org-real--get-all (car partitioned)))
+           (other-children (org-real--get-all (cadr partitioned))))
+      (setq children (org-real-box-collection))
+      (org-real--make-dirty world)
+      (mapc
+       (lambda (flex-child)
+         (org-real--flex-add flex-child box world))
+       flex-children)
+      (mapc
+       (lambda (other-child)
+         (if (not (slot-boundp other-child :rel-box))
+             (org-real--flex-add other-child box world)
+           (org-real--position-box other-child)
+           (org-real--flex-adjust other-child world)))
+       other-children))))
 
 (cl-defmethod org-real--add-headline (headline
                                       (parent org-real-box))
@@ -1687,14 +1723,14 @@ characters if possible."
                            (cddr headline)))
              (children (alist-get 'children partitioned))
              (siblings (alist-get 'siblings partitioned))
-             (pos (goto-char (org-element-property :begin headline)))
-             (columns (org-columns--collect-values))
+             (pos (org-element-property :begin headline))
+             (columns (save-excursion (goto-char pos) 
(org-columns--collect-values)))
              (max-column-length (apply 'max 0
                                        (mapcar
                                         (lambda (column)
                                           (length (cadr (car column))))
                                         columns)))
-             (rel (or (org-entry-get nil "REL") "in"))
+             (rel (save-excursion (goto-char pos) (or (org-entry-get nil 
"REL") "in")))
              (level (if (member rel org-real-children-prepositions)
                         (+ 1 parent-level)
                       parent-level))
@@ -1899,7 +1935,6 @@ set to the :loc slot of each box."
                           t))))
     container-matrix))
 
-
 (defun org-real--parse-headlines ()
   "Create an org real box from the current buffer's headlines."
   (org-columns-get-format)
@@ -1911,14 +1946,13 @@ set to the :loc slot of each box."
          (document (org-real-box :name title
                                  :metadata ""
                                  :locations (list (point-min-marker)))))
-    (org-real--flex-add document world)
+    (org-real--flex-add document world world)
     (mapc
      (lambda (headline)
         (org-real--add-headline headline document))
      headlines)
     world))
 
-
 (defun org-real--to-link (containers)
   "Create a link string from CONTAINERS."
   (concat "real://"



reply via email to

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