From 0fe2fc10c3f30296ae52bf2d56bbc4d31ea076b0 Mon Sep 17 00:00:00 2001 From: ikappaki Date: Tue, 26 Mar 2024 05:13:24 +0000 Subject: [PATCH] relocate codemirror specific logic to the demo --- {src => demo/src}/deps.cljs | 0 .../nextjournal/command_bar/demo/editor.cljs | 43 ++++++++++++-- src/nextjournal/command_bar.cljs | 56 ++++--------------- 3 files changed, 48 insertions(+), 51 deletions(-) rename {src => demo/src}/deps.cljs (100%) diff --git a/src/deps.cljs b/demo/src/deps.cljs similarity index 100% rename from src/deps.cljs rename to demo/src/deps.cljs diff --git a/demo/src/nextjournal/command_bar/demo/editor.cljs b/demo/src/nextjournal/command_bar/demo/editor.cljs index e9311a8..73e26c0 100644 --- a/demo/src/nextjournal/command_bar/demo/editor.cljs +++ b/demo/src/nextjournal/command_bar/demo/editor.cljs @@ -1,8 +1,8 @@ (ns nextjournal.command-bar.demo.editor (:require ["@codemirror/commands" :refer [history historyKeymap]] ["@codemirror/language" :refer [syntaxHighlighting HighlightStyle]] - ["@codemirror/state" :refer [Compartment EditorState]] - ["@codemirror/view" :as view :refer [EditorView]] + ["@codemirror/state" :refer [Compartment EditorState StateField]] + ["@codemirror/view" :as view :refer [keymap EditorView ViewPlugin]] ["@lezer/highlight" :refer [tags]] ["react" :as react] ["react-dom/client" :as react-client] @@ -21,6 +21,37 @@ [reagent.core :as r] [shadow.resource :as rc])) +(defn get-codemirror-bindings [^js state] + ;; Removing everything that doesn't have a fn name for now. Not sure about this yet. + (->> (.. state (facet keymap) flat (filter #(and (or (.-key %) (.-mac %)) (.-run %) (.. % -run -name)))) + (map + (fn [binding] + (let [{:keys [key mac run shift]} (j/lookup binding) + key (or key mac)] + (concat + [{:local? true + :spec (command-bar/normalize-spec key) + :run run + :name (command-bar/get-fn-name run)}] + (when shift + [{:local? true + :spec (command-bar/normalize-spec (str "Shift-" key)) + :run shift + :name (command-bar/get-fn-name run)}]))))) + flatten + (remove nil?))) + +(def extension + #js [(.-extension (.define StateField + (j/lit {:create #(reset! command-bar/!local-bindings (get-codemirror-bindings %)) + :update (fn [_value tr] + #(reset! command-bar/!local-bindings (get-codemirror-bindings (.-state tr))))}))) + (.define ViewPlugin (fn [view] + #js {:update (fn [^js update] + (when (and (.-focusChanged update) (.. update -view -hasFocus)) + (reset! command-bar/!local-bindings (get-codemirror-bindings (.-state update))) + (reset! command-bar/!local-view (.-view update))))}))]) + (def highlight-style (.define HighlightStyle (clj->js [{:tag (.-meta tags) :class "cmt-meta"} @@ -95,7 +126,7 @@ (test-utils/make-state #js [theme (history) - command-bar/extension + extension clojure-mode/default-extensions (syntaxHighlighting highlight-style) (eval-region/extension {:modifier "Meta"}) @@ -123,18 +154,18 @@ {:class "px-[3px] py-[1px] min-w-[16px]"} k])) (str/split (command-bar/get-pretty-spec spec) #" "))) -(defn key-description [{:keys [codemirror? run spec var]}] +(defn key-description [{:keys [local? run spec var]}] [:div.font-mono {:class "text-[12px]"} [:div [keys-view spec] " is bound to " - (when codemirror? + (when local? [:span "CodeMirror's "]) [:span (when-let [ns (some-> var meta :ns)] [:span ns "/"]) [:span.font-bold (command-bar/get-fn-name run)]] - (when codemirror? + (when local? " command")] (when-let [docs (some-> var meta :doc)] [:div.mt-3 docs])]) diff --git a/src/nextjournal/command_bar.cljs b/src/nextjournal/command_bar.cljs index dca662b..5ea3da6 100644 --- a/src/nextjournal/command_bar.cljs +++ b/src/nextjournal/command_bar.cljs @@ -1,8 +1,5 @@ (ns nextjournal.command-bar - (:require ["@codemirror/state" :refer [StateField]] - ["@codemirror/view" :refer [keymap EditorView ViewPlugin]] - [applied-science.js-interop :as j] - [clojure.string :as str] + (:require [clojure.string :as str] [nextjournal.clerk.render.hooks :as hooks] [nextjournal.command-bar.fuzzy :as fuzzy] [nextjournal.command-bar.keybind :as keybind] @@ -10,8 +7,8 @@ (defonce !bindings (reagent/atom [])) (defonce !global-bindings (reagent/atom [])) -(defonce !codemirror-bindings (reagent/atom [])) -(defonce !codemirror-view (reagent/atom nil)) +(defonce !local-bindings (reagent/atom [])) +(defonce !local-view (reagent/atom nil)) (defonce !state (reagent/atom {})) (defn chord->spec [{:keys [shift ctrl meta alt button]}] @@ -67,44 +64,13 @@ (swap! !fn-names assoc n fn-name) fn-name)))) -(defn get-codemirror-bindings [^js state] - ;; Removing everything that doesn't have a fn name for now. Not sure about this yet. - (->> (.. state (facet keymap) flat (filter #(and (or (.-key %) (.-mac %)) (.-run %) (.. % -run -name)))) - (map - (fn [binding] - (let [{:keys [key mac run shift]} (j/lookup binding) - key (or key mac)] - (concat - [{:codemirror? true - :spec (normalize-spec key) - :run run - :name (get-fn-name run)}] - (when shift - [{:codemirror? true - :spec (normalize-spec (str "Shift-" key)) - :run shift - :name (get-fn-name run)}]))))) - flatten - (remove nil?))) - -(def extension - #js [(.-extension (.define StateField - (j/lit {:create #(reset! !codemirror-bindings (get-codemirror-bindings %)) - :update (fn [_value tr] - #(reset! !codemirror-bindings (get-codemirror-bindings (.-state tr))))}))) - (.define ViewPlugin (fn [view] - #js {:update (fn [^js update] - (when (and (.-focusChanged update) (.. update -view -hasFocus)) - (reset! !codemirror-bindings (get-codemirror-bindings (.-state update))) - (reset! !codemirror-view (.-view update))))}))]) - (defn use-watches [] (hooks/use-effect (fn [] - (let [reset-bindings! #(reset! !bindings (concat @!global-bindings @!codemirror-bindings))] + (let [reset-bindings! #(reset! !bindings (concat @!global-bindings @!local-bindings))] (add-watch !global-bindings :global reset-bindings!) - (add-watch !codemirror-bindings :codemirror reset-bindings!) + (add-watch !local-bindings :codemirror reset-bindings!) #(do (remove-watch !global-bindings :global) - (remove-watch !codemirror-bindings :codemirror)))))) + (remove-watch !local-bindings :codemirror)))))) (defn get-pretty-spec [spec] (->> (str/split spec #"-") @@ -127,16 +93,16 @@ "delete" "Del"} (str/lower-case k) (str/capitalize k)))) (str/join " "))) -(defn run-binding [{:keys [codemirror? run]}] - (if codemirror? +(defn run-binding [{:keys [local? run]}] + (if local? (do - (.focus @!codemirror-view) - (js/requestAnimationFrame #(run @!codemirror-view))) + (.focus @!local-view) + (js/requestAnimationFrame #(run @!local-view))) (run))) (defn kill-interactive! [] (swap! !state dissoc :interactive :input/query :pick-list/filtered-items :pick-list/selected-index) - (when-let [cm @!codemirror-view] + (when-let [cm @!local-view] (.focus cm))) (defn make-interactive! [interactive-fn]