From 237f4d9e1aabf50eae07fe807b34783a95dec0e9 Mon Sep 17 00:00:00 2001 From: Weihua Lu Date: Wed, 9 Jun 2021 02:58:03 +0800 Subject: [PATCH] refactor: extract cursor ops to new ns --- src/main/frontend/commands.cljs | 17 ++-- src/main/frontend/components/commit.cljs | 3 +- src/main/frontend/handler/editor.cljs | 30 +++---- src/main/frontend/handler/page.cljs | 5 +- src/main/frontend/state.cljs | 3 +- src/main/frontend/util.cljc | 60 -------------- src/main/frontend/util/cursor.cljs | 99 +++++++++++++++++------- 7 files changed, 102 insertions(+), 115 deletions(-) diff --git a/src/main/frontend/commands.cljs b/src/main/frontend/commands.cljs index 2d5c3e3b0..1bebe0b16 100644 --- a/src/main/frontend/commands.cljs +++ b/src/main/frontend/commands.cljs @@ -1,5 +1,6 @@ (ns frontend.commands (:require [frontend.util :as util] + [frontend.util.cursor :as cursor] [frontend.util.marker :as marker] [frontend.util.priority :as priority] [frontend.date :as date] @@ -302,7 +303,7 @@ (or forward-pos 0)) (or backward-pos 0))] (state/set-block-content-and-last-pos! id new-value new-pos) - (util/move-cursor-to input + (cursor/move-cursor-to input (if (or backward-pos forward-pos) new-pos (+ new-pos 1)))))) @@ -323,7 +324,7 @@ (or forward-pos 0)) (or backward-pos 0))] (state/set-block-content-and-last-pos! id new-value new-pos) - (util/move-cursor-to input new-pos) + (cursor/move-cursor-to input new-pos) (when check-fn (check-fn new-value (dec (count prefix)) new-pos)))) @@ -343,7 +344,7 @@ (or forward-pos 0)) (or backward-pos 0))] (state/set-block-content-and-last-pos! id new-value new-pos) - (util/move-cursor-to input new-pos) + (cursor/move-cursor-to input new-pos) (when check-fn (check-fn new-value (dec (count suffix)) new-pos)))) @@ -367,7 +368,7 @@ (or forward-pos 0)) (or backward-pos 0))] (state/set-block-content-and-last-pos! id new-value new-pos) - (util/move-cursor-to input new-pos) + (cursor/move-cursor-to input new-pos) (when selected? (.setSelectionRange input new-pos (+ new-pos (count selected)))) (when check-fn @@ -383,7 +384,7 @@ (subs edit-content (inc current-pos))) new-pos (count prefix)] (state/set-block-content-and-last-pos! id new-value new-pos) - (util/move-cursor-to input new-pos))) + (cursor/move-cursor-to input new-pos))) (defn get-matched-commands ([text] @@ -410,17 +411,17 @@ (defmethod handle-step :editor/cursor-back [[_ n]] (when-let [input-id (state/get-edit-input-id)] (when-let [current-input (gdom/getElement input-id)] - (util/cursor-move-back current-input n)))) + (cursor/move-cursor-backward current-input n)))) (defmethod handle-step :editor/cursor-forward [[_ n]] (when-let [input-id (state/get-edit-input-id)] (when-let [current-input (gdom/getElement input-id)] - (util/cursor-move-forward current-input n)))) + (cursor/move-cursor-forward current-input n)))) (defmethod handle-step :editor/move-cursor-to-end [[_]] (when-let [input-id (state/get-edit-input-id)] (when-let [current-input (gdom/getElement input-id)] - (util/move-cursor-to-end current-input)))) + (cursor/move-cursor-to-end current-input)))) (defmethod handle-step :editor/clear-current-slash [[_]] (when-let [input-id (state/get-edit-input-id)] diff --git a/src/main/frontend/components/commit.cljs b/src/main/frontend/components/commit.cljs index 97d33bfa8..a272497af 100644 --- a/src/main/frontend/components/commit.cljs +++ b/src/main/frontend/components/commit.cljs @@ -1,6 +1,7 @@ (ns frontend.components.commit (:require [rum.core :as rum] [frontend.util :as util :refer-macros [profile]] + [frontend.util.cursor :as cursor] [clojure.string :as string] [frontend.handler.repo :as repo-handler] [frontend.state :as state] @@ -23,7 +24,7 @@ {:did-update (fn [state] (when-let [input (gdom/getElement "commit-message")] (.focus input) - (util/move-cursor-to-end input)) + (cursor/move-cursor-to-end input)) state)} (mixins/event-mixin (fn [state] diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 61c0ab569..942f8b618 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -91,9 +91,9 @@ new-value (str prefix wrapped-value postfix)] (state/set-edit-content! edit-id new-value) (if empty-selection? - (util/cursor-move-back input (count pattern)) + (cursor/move-cursor-backward input (count pattern)) (let [new-pos (count (str prefix wrapped-value))] - (util/move-cursor-to input new-pos)))))) + (cursor/move-cursor-to input new-pos)))))) (defn bold-format! [] (format-text! config/get-bold)) @@ -127,7 +127,7 @@ (subs value selection-end)) cur-pos (or selection-start cur-pos)] (state/set-edit-content! edit-id new-value) - (util/move-cursor-to input (+ cur-pos forward-pos))))) + (cursor/move-cursor-to input (+ cur-pos forward-pos))))) (defn open-block-in-sidebar! [block-id] @@ -1760,7 +1760,7 @@ (when-let [saved-cursor (get @state/state :editor/last-saved-cursor)] (when-let [input (gdom/getElement id)] (.focus input) - (util/move-cursor-to input saved-cursor)))) + (cursor/move-cursor-to input saved-cursor)))) (defn open-block! [first?] @@ -1904,7 +1904,7 @@ [input] (fn [] (state/set-editor-show-block-search! false) - (util/cursor-move-forward input 2))) + (cursor/move-cursor-forward input 2))) (defn- get-block-tree-insert-pos-after-target "return [target-block sibling? delete-editing-block? editing-block]" @@ -2185,7 +2185,7 @@ s2 (subs value selected-end)] (state/set-edit-content! (state/get-edit-input-id) (str s1 "\n" s2)) - (util/move-cursor-to input (inc selected-start))))) + (cursor/move-cursor-to input (inc selected-start))))) (defn keydown-new-block-handler [state e] (if (state/get-new-block-toggle?) @@ -2309,8 +2309,8 @@ :else (if left? - (util/cursor-move-back input 1) - (util/cursor-move-forward input 1)))))) + (cursor/move-cursor-backward input) + (cursor/move-cursor-forward input)))))) (defn- delete-and-update [^js input start end] (.setRangeText input "" start end) @@ -2340,7 +2340,7 @@ (do (delete-block-aux! next-block false) (state/set-edit-content! input-id (str value "" (:block/content next-block))) - (util/move-cursor-to input current-pos))))) + (cursor/move-cursor-to input current-pos))))) (defn keydown-delete-handler [e] @@ -2470,7 +2470,7 @@ (indent-outdent (not (= :left direction))) (and input pos (when-let [input (state/get-input)] - (util/move-cursor-to input pos))))) + (cursor/move-cursor-to input pos))))) (state/selection?) (do @@ -2506,7 +2506,7 @@ (= (get-current-input-char input) key)) (do (util/stop e) - (util/cursor-move-forward input 1)) + (cursor/move-cursor-forward input)) (contains? (set (keys autopair-map)) key) (do @@ -2887,16 +2887,16 @@ (util/kill-line-after! (state/get-input))) (defn beginning-of-block [] - (util/move-cursor-to (state/get-input) 0)) + (cursor/move-cursor-to (state/get-input) 0)) (defn end-of-block [] - (util/move-cursor-to-end (state/get-input))) + (cursor/move-cursor-to-end (state/get-input))) (defn cursor-forward-word [] - (util/move-cursor-forward-by-word (state/get-input))) + (cursor/move-cursor-forward-by-word (state/get-input))) (defn cursor-backward-word [] - (util/move-cursor-backward-by-word (state/get-input))) + (cursor/move-cursor-backward-by-word (state/get-input))) (defn backward-kill-word [] (let [input (state/get-input)] diff --git a/src/main/frontend/handler/page.cljs b/src/main/frontend/handler/page.cljs index 62f567408..e9b41c24e 100644 --- a/src/main/frontend/handler/page.cljs +++ b/src/main/frontend/handler/page.cljs @@ -4,6 +4,7 @@ [datascript.core :as d] [frontend.state :as state] [frontend.util :as util :refer-macros [profile]] + [frontend.util.cursor :as cursor] [frontend.config :as config] [frontend.handler.common :as common-handler] [frontend.handler.route :as route-handler] @@ -420,8 +421,8 @@ (- (count page-ref-text) (count old-page-ref)) 2)] - (util/move-cursor-to input new-pos))) - (util/cursor-move-forward input 2))) + (cursor/move-cursor-to input new-pos))) + (cursor/move-cursor-forward input 2))) (defn on-chosen-handler [input id q pos format] diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 3b4747e00..cb06f8e7c 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -2,6 +2,7 @@ (:require [frontend.storage :as storage] [rum.core :as rum] [frontend.util :as util :refer-macros [profile]] + [frontend.util.cursor :as cursor] [clojure.string :as string] [cljs-bean.core :as bean] [medley.core :as medley] @@ -746,7 +747,7 @@ ;; it seems to me textarea autoresize is completely broken #_(set! (.-value input) (string/trim content))) (when move-cursor? - (util/move-cursor-to input pos)))))))) + (cursor/move-cursor-to input pos)))))))) (defn clear-edit! [] diff --git a/src/main/frontend/util.cljc b/src/main/frontend/util.cljc index 71d79d61c..c5eb24d6c 100644 --- a/src/main/frontend/util.cljc +++ b/src/main/frontend/util.cljc @@ -621,29 +621,6 @@ (recur (conj res [(.-index m) (first m)])) res))))) -#?(:cljs - (defn cursor-move-back [input n] - (let [{:keys [pos]} (get-caret-pos input) - pos (- pos n)] - (.setSelectionRange input pos pos)))) - -#?(:cljs - (defn cursor-move-forward [input n] - (when input - (let [{:keys [pos]} (get-caret-pos input) - pos (+ pos n)] - (.setSelectionRange input pos pos))))) - -#?(:cljs - (defn move-cursor-to [input n] - (.setSelectionRange input n n))) - -#?(:cljs - (defn move-cursor-to-end - [input] - (let [pos (count (gobj/get input "value"))] - (move-cursor-to input pos)))) - #?(:cljs (defn kill-line-before! [input] @@ -1259,43 +1236,6 @@ (def pprint clojure.pprint/pprint) -#?(:cljs - (defn move-cursor-forward-by-word - [input] - (let [val (.-value input) - current (.-selectionStart input) - current (loop [idx current] - (if (#{\space \newline} (nth-safe val idx)) - (recur (inc idx)) - idx)) - idx (or (->> [(string/index-of val \space current) - (string/index-of val \newline current)] - (remove nil?) - (apply min)) - (count val))] - (move-cursor-to input idx)))) - -#?(:cljs - (defn move-cursor-backward-by-word - [input] - (let [val (.-value input) - current (.-selectionStart input) - prev (or - (->> [(string/last-index-of val \space (dec current)) - (string/last-index-of val \newline (dec current))] - (remove nil?) - (apply max)) - 0) - idx (if (zero? prev) - 0 - (-> - (loop [idx prev] - (if (#{\space \newline} (nth-safe val idx)) - (recur (dec idx)) - idx)) - inc))] - (move-cursor-to input idx)))) - #?(:cljs (defn backward-kill-word [input] diff --git a/src/main/frontend/util/cursor.cljs b/src/main/frontend/util/cursor.cljs index 3d8cc61f1..8efe582f0 100644 --- a/src/main/frontend/util/cursor.cljs +++ b/src/main/frontend/util/cursor.cljs @@ -22,7 +22,7 @@ second int)}) -(defn get-caret-pos +(defn- get-caret-pos [input] (when input (try @@ -34,21 +34,83 @@ (defn move-cursor-to [input n] (.setSelectionRange input n n)) -(defn move-cursor-up [input] +(defn move-cursor-forward + ([input] + (move-cursor-forward input 1)) + ([input n] + (when input + (let [{:keys [pos]} (get-caret-pos input) + pos (+ pos n)] + (move-cursor-to input pos))))) + +(defn move-cursor-backward + ([input] + (move-cursor-backward input 1)) + ([input n] + (when input + (let [{:keys [pos]} (get-caret-pos input) + pos (- pos n)] + (move-cursor-to input pos))))) + +(defn move-cursor-to-end + [input] + (let [pos (count (gobj/get input "value"))] + (move-cursor-to input pos))) + +(defn move-cursor-forward-by-word + [input] + (let [val (.-value input) + current (.-selectionStart input) + current (loop [idx current] + (if (#{\space \newline} (util/nth-safe val idx)) + (recur (inc idx)) + idx)) + idx (or (->> [(string/index-of val \space current) + (string/index-of val \newline current)] + (remove nil?) + (apply min)) + (count val))] + (move-cursor-to input idx))) + +(defn move-cursor-backward-by-word + [input] + (let [val (.-value input) + current (.-selectionStart input) + prev (or + (->> [(string/last-index-of val \space (dec current)) + (string/last-index-of val \newline (dec current))] + (remove nil?) + (apply max)) + 0) + idx (if (zero? prev) + 0 + (-> + (loop [idx prev] + (if (#{\space \newline} (util/nth-safe val idx)) + (recur (dec idx)) + idx)) + inc))] + (move-cursor-to input idx))) + +(defn- move-cursor-up-down + [input direction] (let [elms (-> (gdom/getElement "mock-text") gdom/getChildren array-seq) cusor (-> input - (util/get-caret-pos) + (get-caret-pos) (select-keys [:left :top :pos])) chars (->> elms (map mock-char-pos) (group-by :top)) tops (sort (keys chars)) tops-p (partition-by #(== (:top cusor) %) tops) - prev-t (-> tops-p first last) + line-next + (if (= :up direction) + (-> tops-p first last) + (-> tops-p last first)) lefts - (->> (get chars prev-t) + (->> (get chars line-next) (partition-by (fn [char-pos] (<= (:left char-pos) (:left cusor))))) left-a (-> lefts first last) @@ -59,30 +121,11 @@ (closer left-a cusor left-c))] (move-cursor-to input (:pos closer)))) +(defn move-cursor-up [input] + (move-cursor-up-down input :up)) + (defn move-cursor-down [input] - (let [elms (-> (gdom/getElement "mock-text") - gdom/getChildren - array-seq) - cusor (-> input - (util/get-caret-pos) - (select-keys [:left :top :pos])) - chars (->> elms - (map mock-char-pos) - (group-by :top)) - tops (sort (keys chars)) - tops-p (partition-by #(== (:top cusor) %) tops) - next-t (-> tops-p last first) - lefts - (->> (get chars next-t) - (partition-by (fn [char-pos] - (<= (:left char-pos) (:left cusor))))) - left-a (-> lefts first last) - left-c (-> lefts last first) - closer - (if (< (count lefts) 2) - left-a - (closer left-a cusor left-c))] - (move-cursor-to input (:pos closer)))) + (move-cursor-up-down input :down)) (comment ;; previous implementation of up/down