From 54b7df65a9ac1d33a536baab90550fb143c0a9c7 Mon Sep 17 00:00:00 2001 From: Devon Zuegel Date: Wed, 3 Nov 2021 05:09:33 +0200 Subject: [PATCH] enhance: custom editor command trigger (#3001) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: rename slash → custom-command-trigger * refactor: use command-menu-trigger variable throughout, rather than hard-coded Co-authored-by: Tienson Qin --- src/main/frontend/commands.cljs | 75 ++++++++++++------------ src/main/frontend/components/editor.cljs | 2 +- src/main/frontend/handler/editor.cljs | 70 +++++++++++----------- src/main/frontend/state.cljs | 13 +++- 4 files changed, 83 insertions(+), 77 deletions(-) diff --git a/src/main/frontend/commands.cljs b/src/main/frontend/commands.cljs index 67a497eb1..61e6292c5 100644 --- a/src/main/frontend/commands.cljs +++ b/src/main/frontend/commands.cljs @@ -23,7 +23,6 @@ (defonce *show-commands (atom false)) (defonce *slash-caret-pos (atom nil)) -(defonce slash "/") (defonce *show-block-commands (atom false)) (defonce angle-bracket "<") (defonce *angle-bracket-caret-pos (atom nil)) @@ -48,26 +47,29 @@ "Queries documentation"] "."]]) -(def link-steps [[:editor/input (str slash "link")] - [:editor/show-input [{:command :link - :id :link - :placeholder "Link" - :autoFocus true} - {:command :link - :id :label - :placeholder "Label"}]]]) +(defn link-steps [] + [[:editor/input (str (state/get-editor-command-trigger) "link")] + [:editor/show-input [{:command :link + :id :link + :placeholder "Link" + :autoFocus true} + {:command :link + :id :label + :placeholder "Label"}]]]) -(def image-link-steps [[:editor/input (str slash "link")] - [:editor/show-input [{:command :image-link - :id :link - :placeholder "Link" - :autoFocus true} - {:command :image-link - :id :label - :placeholder "Label"}]]]) +(defn image-link-steps [] + [[:editor/input (str (state/get-editor-command-trigger) "link")] + [:editor/show-input [{:command :image-link + :id :link + :placeholder "Link" + :autoFocus true} + {:command :image-link + :id :label + :placeholder "Label"}]]]) -(def zotero-steps [[:editor/input (str slash "zotero")] - [:editor/show-zotero]]) +(defn zotero-steps [] + [[:editor/input (str (state/get-editor-command-trigger) "zotero")] + [:editor/show-zotero]]) (def *extend-slash-commands (atom [])) @@ -90,19 +92,19 @@ [type] (let [template (util/format "@@%s: @@" type)] - [[:editor/input template {:last-pattern slash + [[:editor/input template {:last-pattern (state/get-editor-command-trigger) :backward-pos 2}]])) (defn embed-page [] (conj - [[:editor/input "{{embed [[]]}}" {:last-pattern slash + [[:editor/input "{{embed [[]]}}" {:last-pattern (state/get-editor-command-trigger) :backward-pos 4}]] [:editor/search-page :embed])) (defn embed-block [] - [[:editor/input "{{embed (())}}" {:last-pattern slash + [[:editor/input "{{embed (())}}" {:last-pattern (state/get-editor-command-trigger) :backward-pos 4}] [:editor/search-block :embed]]) @@ -232,13 +234,13 @@ ["Block reference" [[:editor/input "(())" {:backward-pos 2}] [:editor/search-block :reference]] "Create a backlink to a block"] ["Block embed" (embed-block) "Embed a block here" "Embed a block here"] - ["Link" link-steps "Create a HTTP link"] - ["Image link" image-link-steps "Create a HTTP link to a image"] + ["Link" (link-steps) "Create a HTTP link"] + ["Image link" (image-link-steps) "Create a HTTP link to a image"] (when (state/markdown?) ["Underline" [[:editor/input "" - {:last-pattern slash + {:last-pattern (state/get-editor-command-trigger) :backward-pos 6}]] "Create a underline text decoration"]) - ["Template" [[:editor/input "/" nil] + ["Template" [[:editor/input (state/get-editor-command-trigger) nil] [:editor/search-template]] "Insert a created template here"] (cond (and (util/electron?) (config/local-db? (state/get-current-repo))) @@ -277,7 +279,7 @@ ;; advanced [["Query" [[:editor/input "{{query }}" {:backward-pos 2}]] query-doc] - ["Zotero" zotero-steps "Import Zotero journal article"] + ["Zotero" (zotero-steps) "Import Zotero journal article"] ["Query table function" [[:editor/input "{{function }}" {:backward-pos 2}]] "Create a query table function"] ["Calculator" [[:editor/input "```calc\n\n```" {:backward-pos 4}] [:codemirror/focus]] "Insert a calculator"] @@ -290,19 +292,19 @@ text)) "Draw a graph with Excalidraw"] (when (util/zh-CN-supported?) - ["Embed Bilibili video" [[:editor/input "{{bilibili }}" {:last-pattern slash + ["Embed Bilibili video" [[:editor/input "{{bilibili }}" {:last-pattern (state/get-editor-command-trigger) :backward-pos 2}]]]) ["Embed HTML " (->inline "html")] - ["Embed Youtube video" [[:editor/input "{{youtube }}" {:last-pattern slash + ["Embed Youtube video" [[:editor/input "{{youtube }}" {:last-pattern (state/get-editor-command-trigger) :backward-pos 2}]]] ["Embed Youtube timestamp" [[:youtube/insert-timestamp]]] - ["Embed Vimeo video" [[:editor/input "{{vimeo }}" {:last-pattern slash + ["Embed Vimeo video" [[:editor/input "{{vimeo }}" {:last-pattern (state/get-editor-command-trigger) :backward-pos 2}]]] - ["Embed Twitter tweet" [[:editor/input "{{tweet }}" {:last-pattern slash + ["Embed Twitter tweet" [[:editor/input "{{tweet }}" {:last-pattern (state/get-editor-command-trigger) :backward-pos 2}]]]] @*extend-slash-commands @@ -333,12 +335,11 @@ (defn insert! [id value - {:keys [last-pattern postfix-fn backward-pos forward-pos - end-pattern] - :or {last-pattern slash} + {:keys [last-pattern postfix-fn backward-pos forward-pos end-pattern] :as _option}] (when-let [input (gdom/getElement id)] - (let [edit-content (gobj/get input "value") + (let [last-pattern (or last-pattern (state/get-editor-command-trigger)) + edit-content (gobj/get input "value") current-pos (cursor/pos input) current-pos (or (when (and end-pattern (string? end-pattern)) @@ -470,7 +471,7 @@ (defn get-command-input [edit-content] (when-not (string/blank? edit-content) - (let [result (last (util/split-last slash edit-content))] + (let [result (last (util/split-last (state/get-editor-command-trigger) edit-content))] (if (string/blank? result) nil result)))) @@ -518,7 +519,7 @@ (let [edit-content (gobj/get current-input "value") current-pos (cursor/pos current-input) prefix (subs edit-content 0 current-pos) - prefix (util/replace-last slash prefix "" (boolean space?)) + prefix (util/replace-last (state/get-editor-command-trigger) prefix "" (boolean space?)) new-value (str prefix (subs edit-content current-pos))] (state/set-block-content-and-last-pos! input-id diff --git a/src/main/frontend/components/editor.cljs b/src/main/frontend/components/editor.cljs index 3567eb194..e393d1c14 100644 --- a/src/main/frontend/components/editor.cljs +++ b/src/main/frontend/components/editor.cljs @@ -304,7 +304,7 @@ (let [command (:command (first input-option))] [:div.p-2.rounded-md.shadow-lg (for [{:keys [id placeholder type autoFocus] :as input-item} input-option] - [:div.my-3 + [:div.my-3 {:key id} [:input.form-input.block.w-full.pl-2.sm:text-sm.sm:leading-5 (merge (cond-> diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 7af3ef386..648d32136 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -1467,10 +1467,6 @@ (util/format "[[%s][%s]]" url file-name)) nil))) -(defn- get-asset-link - [url] - (str "/" url)) - (defn ensure-assets-dir! [repo] (let [repo-dir (config/get-repo-dir repo) @@ -1582,7 +1578,7 @@ (if file (.-name file) (if image? "image" "asset")) image?) format - {:last-pattern (if drop-or-paste? "" commands/slash) + {:last-pattern (if drop-or-paste? "" (state/get-editor-command-trigger)) :restore? true}))))) (p/finally (fn [] @@ -1599,7 +1595,7 @@ (insert-command! id (get-asset-file-link format signed-url file-name true) format - {:last-pattern (if drop-or-paste? "" commands/slash) + {:last-pattern (if drop-or-paste? "" (state/get-editor-command-trigger)) :restore? true}) (reset! *asset-uploading? false) @@ -1738,7 +1734,7 @@ last-command (and last-slash-caret-pos (subs edit-content last-slash-caret-pos pos))] (when (> pos 0) (or - (and (= \/ (util/nth-safe edit-content (dec pos))) + (and (= (state/get-editor-command-trigger) (util/nth-safe edit-content (dec pos))) @commands/*initial-commands) (and last-command (commands/get-matched-commands last-command))))) @@ -1864,8 +1860,7 @@ blocks-dom-nodes))] (state/set-selection-blocks! blocks))))))))) -(defn- get-link - [format link label] +(defn- get-link [format link label] (let [link (or link "") label (or label "")] (case (keyword format) @@ -1881,27 +1876,27 @@ :markdown (util/format "![%s](%s)" label link) :org (util/format "[[%s]]")))) -(defn handle-command-input - [command id format m] +(defn handle-command-input [command id format m] + ;; TODO: Add error handling for when user doesn't provide a required field. + ;; (The current behavior is to just revert back to the editor.) (case command - :link - (let [{:keys [link label]} m] - (if (and (string/blank? link) - (string/blank? label)) - nil - (insert-command! id - (get-link format link label) - format - {:last-pattern (str commands/slash "link")}))) - :image-link - (let [{:keys [link label]} m] - (if (and (string/blank? link) - (string/blank? label)) - nil - (insert-command! id - (get-image-link format link label) - format - {:last-pattern (str commands/slash "link")}))) + + :link (let [{:keys [link label]} m] + (when-not (or (string/blank? link) (string/blank? label)) + (insert-command! + id + (get-link format link label) + format + {:last-pattern (str (state/get-editor-command-trigger) "link")}))) + + :image-link (let [{:keys [link label]} m] + (when (not (string/blank? link)) + (insert-command! + id + (get-image-link format link label) + format + {:last-pattern (str (state/get-editor-command-trigger) "link")}))) + nil) (state/set-editor-show-input! nil) @@ -1995,14 +1990,15 @@ (let [input (state/get-input) pos (cursor/pos input) last-input-char (util/nth-safe (.-value input) (dec pos))] - (case last-input-char - "/" + ;; TODO: is it cross-browser compatible? ;; (not= (gobj/get native-e "inputType") "insertFromPaste") + (if (= last-input-char (state/get-editor-command-trigger)) (when (seq (get-matched-commands input)) (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)) - (reset! commands/*show-commands true)) - "<" + (reset! commands/*show-commands true))) + + (if (= last-input-char commands/angle-bracket) (when (seq (get-matched-block-commands input)) (reset! commands/*angle-bracket-caret-pos (cursor/get-caret-pos input)) (reset! commands/*show-block-commands true)) @@ -2629,7 +2625,7 @@ (delete-block! repo false)) (and (> current-pos 1) - (= (util/nth-safe value (dec current-pos)) commands/slash)) + (= (util/nth-safe value (dec current-pos)) (state/get-editor-command-trigger))) (do (util/stop e) (reset! *slash-caret-pos nil) @@ -2821,8 +2817,8 @@ (when (and (= "〈" c) (= "《" (util/nth-safe value (dec (dec current-pos)))) (> current-pos 0)) - (commands/handle-step [:editor/input "<" {:last-pattern "《〈" - :backward-pos 0}]) + (commands/handle-step [:editor/input commands/angle-bracket {:last-pattern "《〈" + :backward-pos 0}]) (reset! commands/*angle-bracket-caret-pos (cursor/get-caret-pos input)) (reset! commands/*show-block-commands true)) @@ -2833,7 +2829,7 @@ (not= (util/nth-safe value current-pos) "]"))) (state/set-editor-show-page-search-hashtag! false))) - (when (and @*show-commands (not= key-code 191)) ; not / + (when (and @*show-commands (not= key-code 191)) ; not / TODO: is this the .charCodeAt or the event code? (let [matched-commands (get-matched-commands input)] (if (seq matched-commands) (do diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index 05fc5db66..3df6c0d4a 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -349,6 +349,15 @@ (get-in @state [:me :preferred_format] "markdown"))))) +;; TODO: consider adding a pane in Settings to set this through the GUI (rather +;; than having to go through the config.edn file) +(defn get-editor-command-trigger + ([] (get-editor-command-trigger (get-current-repo))) + ([repo-url] + (or + (:editor/command-trigger (get-config repo-url)) ;; Get from user config + "/"))) ;; Set the default + (defn markdown? [] (= (keyword (get-preferred-format)) @@ -1163,8 +1172,8 @@ (if (util/mobile?) false (get (get (sub-config) (get-current-repo)) - :ui/enable-tooltip? - true))) + :ui/enable-tooltip? + true))) (defn show-command-doc? []