diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index f0a53b61dc..f48e87673f 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -1824,12 +1824,11 @@ ;; TODO: is it cross-browser compatible? ;; (not= (gobj/get native-e "inputType") "insertFromPaste") (cond - ;; By default, "/" is also used as namespace separator in Logseq. (and (= last-input-char (state/get-editor-command-trigger)) - #_(not (contains? #{:page-search-hashtag} (state/sub :editor/action))) + ;; By default, "/" is also used as namespace separator in Logseq. + (not (contains? #{:page-search-hashtag} (state/sub :editor/action))) (or (= 1 pos) (start-of-new-word? input pos))) (do - (prn :NEW-WORD? (or (= 1 pos) (start-of-new-word? input pos))) (state/set-editor-action-data! {:pos (cursor/get-caret-pos input)}) (commands/reinit-matched-commands!) (state/set-editor-show-commands!)) @@ -2843,7 +2842,6 @@ (gobj/get e "key") (gobj/getValueByKeys e "event_" "code")) (util/event-is-composing? e true)]) ;; #3440 - format (:format (get-state)) last-key-code (state/get-last-key-code) blank-selected? (string/blank? (util/get-selected-text)) non-enter-processed? (and is-processed? ;; #3251 @@ -2852,14 +2850,18 @@ (cond ;; When you type something after / (and (= :commands (state/get-editor-action)) (not= k (state/get-editor-command-trigger))) - (let [matched-commands (get-matched-commands input)] - (if (seq matched-commands) - (reset! commands/*matched-commands matched-commands) - (state/clear-editor-action!))) + (if (= (state/get-editor-command-trigger) (second (re-find #"(\S+)\s+$" value))) + (state/clear-editor-action!) + (let [matched-commands (get-matched-commands input)] + (prn :KEYUP {:k k :input input :value (gobj/get input "value")}) + (if (seq matched-commands) + (reset! commands/*matched-commands matched-commands) + (state/clear-editor-action!)))) ;; When you type search text after < (and when you release shift after typing <) (and (= :block-commands editor-action) (not= key-code 188)) ; not < - (let [matched-block-commands (get-matched-block-commands input)] + (let [matched-block-commands (get-matched-block-commands input) + format (:format (get-state))] (if (seq matched-block-commands) (cond (= key-code 9) ;tab @@ -2876,7 +2878,7 @@ (state/clear-editor-action!))) ;; When you type two spaces after a command character (may always just be handled by the above instead?) - (and (contains? #{:commands :block-commands} (state/get-editor-action)) + (and (contains? #{:block-commands} (state/get-editor-action)) (= c (util/nth-safe value (dec (dec current-pos))) " ")) (state/clear-editor-action!) diff --git a/src/test/frontend/handler/editor_test.cljs b/src/test/frontend/handler/editor_test.cljs index 6b65613d54..61a32b855a 100644 --- a/src/test/frontend/handler/editor_test.cljs +++ b/src/test/frontend/handler/editor_test.cljs @@ -2,6 +2,7 @@ (:require [frontend.handler.editor :as editor] [clojure.test :refer [deftest is testing are]] [frontend.state :as state] + [frontend.util :as util] [frontend.util.cursor :as cursor])) (deftest extract-nearest-link-from-text-test @@ -66,8 +67,50 @@ "TODO" "## TODO content" "## DOING content" "DONE" "DONE content" "content")) +(defn- keyup-handler + "Spied version of editor/keyup-handler" + [{:keys [value cursor-pos action commands] + ;; Default to some commands matching which matches default behavior for most + ;; completion scenarios + :or {commands [:fake-command]}}] + ;; Reset editor action in order to test result + (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) + util/get-selected-text (constantly nil) + cursor/pos (constantly pos)] + ((editor/keyup-handler nil input nil) + #js {:key (subs value (dec (count value)))} + nil)))) + +(deftest ^:focus keyup-handler-test + (testing "Command completion" + (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 "/zz" + :action :commands + :commands []}) + (is (= nil (state/get-editor-action)) + "Completion closed if there no matching commands") + + (keyup-handler {:value "/ " :action :commands}) + (is (= nil (state/get-editor-action)) + "Completion closed after a space follows /") + + (keyup-handler {:value "/block " :action :commands}) + (is (= :commands (state/get-editor-action)) + "Completion stays open if space is part of the search term for /")) + ;; Reset state + (state/set-editor-action! nil)) + (defn- handle-last-input-handler - "Spied version of editor/keydown-not-matched-handler" + "Spied version of editor/handle-last-input" [{:keys [value cursor-pos]}] ;; Reset editor action in order to test result (state/set-editor-action! nil)