From a8c9daad072145bfea085482f2cc89a014896aa0 Mon Sep 17 00:00:00 2001 From: llcc Date: Thu, 16 Dec 2021 20:30:30 +0800 Subject: [PATCH] enhance(dwim): re-number its items when dwim in an ordered list (#3358) * enhance(dwim): re-number list if dwim in ordered list * fix: regexp for matching a list item * enhance: don't enable dwim in list if cursor is at beginning of item Co-authored-by: leizhe --- src/main/frontend/handler/editor.cljs | 46 +++++++++++++++++++-------- src/main/frontend/util/list.cljs | 20 ++++++++++++ src/main/frontend/util/thingatpt.cljs | 4 +-- 3 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 src/main/frontend/util/list.cljs diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 853d3194b..0c0c37209 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -47,6 +47,7 @@ [frontend.util.page-property :as page-property] [frontend.util.property :as property] [frontend.util.thingatpt :as thingatpt] + [frontend.util.list :as list] [goog.dom :as gdom] [goog.dom.classes :as gdom-classes] [goog.object :as gobj] @@ -2422,6 +2423,34 @@ (cursor/move-cursor-backward input move-to-pos))) (insert "\n"))))))) +(defn- dwim-in-list + [state] + (when-not (auto-complete?) + (let [{:keys [block]} (get-state)] + (when block + (let [input (state/get-input)] + (when-let [item (thingatpt/list-item-at-point input)] + (let [{:keys [full-content indent bullet checkbox ordered _]} item + current-bullet (cljs.reader/read-string bullet) + next-bullet (if ordered (str (inc current-bullet) ".") bullet) + checkbox (when checkbox "[ ] ")] + (if (= (count full-content) + (+ (if ordered (+ (count bullet) 2) 2) (when checkbox (count checkbox)))) + (delete-and-update input (cursor/line-beginning-pos input) (cursor/line-end-pos input)) + (do (cursor/move-cursor-to-line-end input) + (insert (str "\n" indent next-bullet " " checkbox)) + (when ordered + (let [bullet-atom (atom (inc current-bullet))] + (while (when-let [next-item (list/get-next-item input)] + (swap! bullet-atom inc) + (let [{:keys [full-content start end]} next-item + new-bullet @bullet-atom] + (delete-and-update input start end) + (insert (string/replace-first full-content (:bullet next-item) new-bullet)) + true)) + nil) + (cursor/move-cursor-to input (+ (:end item) (count next-bullet) 2))))))))))))) + (defn- keydown-new-block [state] (when-not (auto-complete?) @@ -2445,7 +2474,7 @@ (when (thingatpt/get-setting :properties?) (thingatpt/properties-at-point input)) (when (thingatpt/get-setting :list?) - (and (cursor/end-of-line? input) ;; only apply DWIM when cursor at EOL + (and (not (cursor/beginning-of-line? input)) (thingatpt/list-item-at-point input))))] (cond thing-at-point @@ -2466,19 +2495,8 @@ "page-ref" (when-not (string/blank? (:link thing-at-point)) (insert-first-page-block-if-not-exists! (:link thing-at-point)) (route-handler/redirect-to-page! (:link thing-at-point))) - "list-item" - (let [{:keys [full-content indent bullet checkbox ordered _]} thing-at-point - next-bullet (if ordered - (str (inc (cljs.reader/read-string bullet)) ".") - bullet) - checkbox (when checkbox "[ ] ")] - (if (= (count full-content) - (+ (if ordered (+ (count bullet) 2) 2) (when checkbox (count checkbox)))) - (delete-and-update input (cursor/line-beginning-pos input) (cursor/line-end-pos input)) - (do (cursor/move-cursor-to-line-end input) - (insert (str "\n" indent next-bullet " " checkbox))))) - "properties-drawer" - (dwim-in-properties state)) + "list-item" (dwim-in-list state) + "properties-drawer" (dwim-in-properties state)) (and (string/blank? content) diff --git a/src/main/frontend/util/list.cljs b/src/main/frontend/util/list.cljs new file mode 100644 index 000000000..3eb2a1c03 --- /dev/null +++ b/src/main/frontend/util/list.cljs @@ -0,0 +1,20 @@ +(ns frontend.util.list + (:require [frontend.util.thingatpt :as thingatpt] + [frontend.util.cursor :as cursor])) + +(defn- get-prev-item [& [input]] + (when-let [item (thingatpt/list-item-at-point input)] + (let [{:keys [bullet ordered]} item] + (when-not (or (cursor/textarea-cursor-first-row? input) + (and ordered + (= bullet "1"))) + (cursor/move-cursor-up input) + (thingatpt/list-item-at-point input))))) + +(defn- get-next-item [& [input]] + (when-let [item (thingatpt/list-item-at-point input)] + (let [{:keys [_bullet _ordered]} item] + (when-not (cursor/textarea-cursor-last-row? input) + (cursor/move-cursor-down input) + (thingatpt/list-item-at-point input))))) + diff --git a/src/main/frontend/util/thingatpt.cljs b/src/main/frontend/util/thingatpt.cljs index 701d1f681..16e70641f 100644 --- a/src/main/frontend/util/thingatpt.cljs +++ b/src/main/frontend/util/thingatpt.cljs @@ -92,8 +92,8 @@ (defn- get-list-item-indent&bullet [line] (when-not (string/blank? line) - (or (re-matches #"^([ \t\r]*)(\+|\*|-) (\[[X ]\])*.*$" line) - (re-matches #"^([\s]*)(\d+)\. (\[[X ]\])*.*$" line)))) + (or (re-matches #"^([ \t\r]*)(\+|\*|-){1} (\[[X ]\])?.*$" line) + (re-matches #"^([\s]*)(\d+){1}\. (\[[X ]\])?.*$" line)))) (defn list-item-at-point [& [input]] (when-let [line (line-at-point input)]