|
17 | 17 | (defn- empty-seq? [zloc]
|
18 | 18 | (and (z/seq? zloc) (not (seq (z/sexpr zloc)))))
|
19 | 19 |
|
20 |
| -;; helper |
21 | 20 | (defn- move-n [loc f n]
|
22 | 21 | (if (= 0 n)
|
23 | 22 | loc
|
|
45 | 44 | (take-while p?)
|
46 | 45 | (map z/node))))
|
47 | 46 |
|
| 47 | +(defn- reduce-into-zipper |
| 48 | + "A thread-first-friendly reducer" |
| 49 | + [zloc f items] |
| 50 | + (reduce f zloc items)) |
| 51 | + |
| 52 | +(defn- linebreak-and-comment-nodes |
| 53 | + "Return vector of all linebreak and comment nodes from whitespace and comment nodes from `zloc` moving via `f` " |
| 54 | + [zloc f] |
| 55 | + (->> (-> zloc |
| 56 | + f |
| 57 | + (nodes-by-dir f ws/whitespace-or-comment?)) |
| 58 | + (filterv #(or (nd/linebreak? %) (nd/comment? %))))) |
| 59 | + |
48 | 60 | (defn- remove-first-if-ws [nodes]
|
49 | 61 | (when (seq nodes)
|
50 | 62 | (if (nd/whitespace? (first nodes))
|
51 | 63 | (rest nodes)
|
52 | 64 | nodes)))
|
53 | 65 |
|
54 |
| -(defn- remove-ws-or-comment [zloc] |
55 |
| - (if-not (ws/whitespace-or-comment? zloc) |
56 |
| - zloc |
57 |
| - (recur (z/remove* zloc)))) |
58 |
| - |
59 | 66 | (defn- create-seq-node
|
60 | 67 | "Creates a sequence node of given type `t` with node values of `v`"
|
61 | 68 | [t v]
|
|
457 | 464 | zloc))
|
458 | 465 |
|
459 | 466 | (defn- join-seqs [left right]
|
460 |
| - (let [lefts (-> left z/node nd/children) |
| 467 | + (let [rights (-> right z/node nd/children) |
461 | 468 | ws-nodes (-> (z/right* left) (nodes-by-dir z/right* ws/whitespace-or-comment?))
|
462 |
| - rights (-> right z/node nd/children)] |
| 469 | + ws-nodes (if (seq ws-nodes) |
| 470 | + ws-nodes |
| 471 | + [(nd/spaces 1)]) |
| 472 | + zloc (-> left |
| 473 | + (reduce-into-zipper z/append-child* ws-nodes) |
| 474 | + (reduce-into-zipper z/append-child* rights))] |
| 475 | + (-> zloc |
| 476 | + (u/remove-right-while ws/whitespace-or-comment?) |
| 477 | + z/right* |
| 478 | + u/remove-and-move-left |
| 479 | + z/down |
| 480 | + z/rightmost* |
| 481 | + (move-n z/left* (dec (count rights)))))) |
463 | 482 |
|
| 483 | +(defn- join-strings [left right] |
| 484 | + (let [cmts-and-nls (linebreak-and-comment-nodes left z/right*) |
| 485 | + cmts-and-nls (when (seq cmts-and-nls) |
| 486 | + (into [(nd/spaces 1)] cmts-and-nls))] |
464 | 487 | (-> right
|
465 | 488 | z/remove*
|
466 |
| - remove-ws-or-comment |
467 |
| - z/up |
468 |
| - (z/insert-left (create-seq-node :vector |
469 |
| - (concat lefts |
470 |
| - ws-nodes |
471 |
| - rights))) |
472 |
| - z/remove |
473 |
| - (global-find-by-node (first rights))))) |
474 |
| - |
475 |
| -(defn- join-strings [left right] |
476 |
| - (-> right |
477 |
| - z/remove* |
478 |
| - remove-ws-or-comment |
479 |
| - (z/replace (nd/string-node (str (-> left z/node nd/sexpr) |
480 |
| - (-> right z/node nd/sexpr)))))) |
| 489 | + z/left |
| 490 | + (u/remove-right-while ws/whitespace-or-comment?) |
| 491 | + ;; sexpr is safe on strings |
| 492 | + (z/replace (nd/string-node (str (-> left z/node nd/sexpr) |
| 493 | + (-> right z/node nd/sexpr)))) |
| 494 | + (reduce-into-zipper z/insert-right* (reverse cmts-and-nls))))) |
481 | 495 |
|
482 | 496 | (defn join
|
483 |
| - "Join S-expression to the left and right of current loc. Also works for strings. |
484 |
| -
|
485 |
| - - `[[1 2] |[3 4]] => [[1 2 3 4]]` |
486 |
| - - `[\"Hello \" | \"World\"] => [\"Hello World\"]`" |
| 497 | + "Returns `zloc` with sequence to the left joined to sequence to the right. |
| 498 | + Also works for strings. |
| 499 | + If sequence types differ, uses sequence type to the left. |
| 500 | +
|
| 501 | + - `[1 2] |[3 4] => [1 2 |3 4]` |
| 502 | + - `[1 2]| [3 4] => [1 2 |3 4]` |
| 503 | + - `{:a 1} |(:b 2) => `{:a 1 :b 2}` |
| 504 | + - `[\"Hello\" | \"World\"] => [|\"HelloWorld\"]`" |
487 | 505 | [zloc]
|
488 | 506 | (let [left (some-> zloc z/left)
|
489 | 507 | right (if (some-> zloc z/node nd/whitespace?) (z/right zloc) zloc)]
|
|
0 commit comments