From cfd5ea9d0b7e9873a94732a2e22db72260fb479d Mon Sep 17 00:00:00 2001 From: Mega Yu Date: Thu, 17 Apr 2025 20:28:23 +0800 Subject: [PATCH] =?UTF-8?q?enhance=20the=C2=A0/=C2=A0input=20tolerance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/frontend/commands.cljs | 9 +++++++- src/main/frontend/components/editor.cljs | 4 +++- src/main/frontend/handler/editor.cljs | 25 +++++++++++++--------- src/test/frontend/handler/editor_test.cljs | 19 +++++++++++----- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/main/frontend/commands.cljs b/src/main/frontend/commands.cljs index ee19b85269..b4c50a643c 100644 --- a/src/main/frontend/commands.cljs +++ b/src/main/frontend/commands.cljs @@ -299,6 +299,7 @@ (let [heading (str "Heading " level)] [heading (->heading level) heading (str "h-" level)])) (range 1 7))) +(defonce *latest-matched-command (atom "")) (defonce *matched-commands (atom nil)) (defonce *initial-commands (atom nil)) @@ -474,12 +475,18 @@ (defn init-commands! [get-page-ref-text] (let [commands (commands-map get-page-ref-text)] + (reset! *latest-matched-command "") (reset! *initial-commands commands) (reset! *matched-commands commands))) +(defn set-matched-commands! + [command matched-commands] + (reset! *latest-matched-command command) + (reset! *matched-commands matched-commands)) + (defn reinit-matched-commands! [] - (reset! *matched-commands @*initial-commands)) + (set-matched-commands! "" @*initial-commands)) (defn restore-state [] diff --git a/src/main/frontend/components/editor.cljs b/src/main/frontend/components/editor.cljs index 98a04d3794..346f8e803d 100644 --- a/src/main/frontend/components/editor.cljs +++ b/src/main/frontend/components/editor.cljs @@ -38,6 +38,8 @@ [react-draggable] [rum.core :as rum])) +(defonce no-matched-coomands [["No matched commands" [[:editor/move-cursor-to-end]]]]) + (defn filter-commands [page? commands] (if page? @@ -56,7 +58,7 @@ _ (when (state/get-editor-action) (reset! *matched matched')) page? (db/page? (db/entity (:db/id (state/get-edit-block)))) - matched (filter-commands page? @*matched)] + matched (or (filter-commands page? @*matched) no-matched-coomands)] (ui/auto-complete matched {:get-group-name diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 6a39c91edb..90aaf3728b 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -1773,23 +1773,25 @@ [property q] (search/property-value-search property q)) -(defn get-matched-commands +(defn get-last-command [input] (try (let [edit-content (or (gobj/get input "value") "") pos (cursor/pos input) last-slash-caret-pos (:pos (:pos (state/get-editor-action-data))) last-command (and last-slash-caret-pos (subs edit-content last-slash-caret-pos pos))] - (when (> pos 0) - (or - (and (= commands/command-trigger (util/nth-safe edit-content (dec pos))) - @commands/*initial-commands) - (and last-command - (commands/get-matched-commands last-command))))) + (when (> pos 0) last-command)) (catch :default e (js/console.error e) nil))) +(defn get-matched-commands + [command] + (condp = command + nil nil + "" @commands/*initial-commands + (commands/get-matched-commands command))) + (defn auto-complete? [] (or @*asset-uploading? @@ -3206,10 +3208,13 @@ (and (= :commands (state/get-editor-action)) (not= k commands/command-trigger)) (if (= commands/command-trigger (second (re-find #"(\S+)\s+$" value))) (state/clear-editor-action!) - (let [matched-commands (get-matched-commands input)] + (let [command (get-last-command input) + matched-commands (get-matched-commands command)] (if (seq matched-commands) - (reset! commands/*matched-commands matched-commands) - (state/clear-editor-action!)))) + (commands/set-matched-commands! command matched-commands) + (if (> (- (count command) (count @commands/*latest-matched-command)) 1) + (state/clear-editor-action!) + (reset! commands/*matched-commands nil))))) :else (default-case-for-keyup-handler input current-pos k code is-processed?)) diff --git a/src/test/frontend/handler/editor_test.cljs b/src/test/frontend/handler/editor_test.cljs index 2dfa6841d9..f330141b51 100644 --- a/src/test/frontend/handler/editor_test.cljs +++ b/src/test/frontend/handler/editor_test.cljs @@ -82,8 +82,10 @@ (state/set-editor-action! action) ;; Default cursor pos to end of line (let [pos (or cursor-pos (count value)) - input #js {:value value}] - (with-redefs [editor/get-matched-commands (constantly commands) + input #js {:value value} + command (subs value 1)] + (with-redefs [editor/get-last-command (constantly command) + editor/get-matched-commands (constantly commands) ;; Ignore as none of its behaviors are tested editor/default-case-for-keyup-handler (constantly nil) cursor/pos (constantly pos)] @@ -93,11 +95,12 @@ (deftest keyup-handler-test (testing "Command autocompletion" - (keyup-handler {:value "/b" + ;; default last matching command is "" + (keyup-handler {:value "/z" :action :commands - :commands [:fake-command]}) + :commands []}) (is (= :commands (state/get-editor-action)) - "Completion stays open if there is a matching command") + "Completion stays open if no matches but differs by 1 character from last matching command") (keyup-handler {:value "/zz" :action :commands @@ -105,6 +108,12 @@ (is (= nil (state/get-editor-action)) "Completion closed if there no matching commands") + (keyup-handler {:value "/b" + :action :commands + :commands [:fake-command]}) + (is (= :commands (state/get-editor-action)) + "Completion stays open if there is a matching command") + (keyup-handler {:value "/ " :action :commands}) (is (= nil (state/get-editor-action)) "Completion closed after a space follows /")