Browse Source

enhance: ESC on code back to raw editor

Also, removed :editor/pending-type-block.
Tienson Qin 1 year ago
parent
commit
ccb6ee48e4

+ 3 - 42
src/main/frontend/components/block.cljs

@@ -2760,7 +2760,8 @@
                      (count (:block/_refs block))
                      (rum/react *refs-count))
         table? (:table? config)
-        type-block-editor? (contains? #{:code} (:logseq.property.node/display-type block))
+        type-block-editor? (and (contains? #{:code} (:logseq.property.node/display-type block))
+                                (not= (:db/id block) (:db/id (state/sub :editor/raw-mode-block))))
         config (assoc config :block-parent-id block-id)]
     [:div.block-content-or-editor-wrap
      {:class (when (:page-title? config) "ls-page-title-container")
@@ -3588,12 +3589,6 @@
 
 (declare ->hiccup)
 
-(defn get-cm-instance
-  [^js target]
-  (when target
-    (when-let [node (util/rec-get-node target "ls-code-editor-wrap")]
-      (some-> node (.querySelector ".CodeMirror") (.-CodeMirror)))))
-
 (defn- get-code-mode-by-lang
   [lang]
   (some (fn [m] (when (= (.-name m) lang) (.-mode m))) js/window.CodeMirror.modeInfo))
@@ -3619,13 +3614,6 @@
         *mode-ref (rum/use-ref nil)
         *actions-ref (rum/use-ref nil)]
 
-    (rum/use-effect!
-     (fn []
-       (when (= (some-> (state/sub :editor/pending-type-block) :block :block/uuid) (:block/uuid block))
-         (util/schedule #(some-> (rum/deref *mode-ref) (.click)))
-         (state/set-state! :editor/pending-type-block nil)))
-     [])
-
     (when options
       (let [html-export? (:html-export? config)
             {:keys [lines language]} options
@@ -3672,7 +3660,7 @@
                                  (shui/popup-show! target
                                                    #(src-lang-picker block
                                                                      (fn [lang ^js e]
-                                                                       (when-let [^js cm (get-cm-instance target)]
+                                                                       (when-let [^js cm (util/get-cm-instance target)]
                                                                          (if-let [mode (get-code-mode-by-lang lang)]
                                                                            (.setOption cm "mode" mode)
                                                                            (throw (ex-info "code mode not found"
@@ -4046,33 +4034,6 @@
           {:debug-id page})
          [:div.only-page-blocks items]))]))
 
-(rum/defc setup-editing-effects
-  [editing-block]
-  (let [container-id (some-> (:editor/container-id @state/state) (deref))
-        uuid' (:block/uuid editing-block)]
-    (rum/use-effect!
-     (fn []
-       (case (:logseq.property.node/display-type editing-block)
-         :code
-         (let [cursor-pos (some-> (:editor/cursor-range @state/state) (deref) (count))
-               direction (:block.editing/direction editing-block)
-               pos (:block.editing/pos editing-block)
-               target (js/document.querySelector
-                       (util/format ".select-language[blockid=\"%s\"][containerid=\"%s\"]" uuid' container-id))]
-           (when-let [cm (get-cm-instance target)]
-             (let [to-line (case direction
-                             :up (.lastLine cm)
-                             (case pos
-                               :max (.lastLine cm)
-                               0))]
-               ;; move to friendly cursor
-               (doto cm
-                 (.focus)
-                 (.setCursor to-line (or cursor-pos 0))))))
-         :dune))
-     [editing-block]))
-  nil)
-
 ;; headers to hiccup
 (defn ->hiccup
   [blocks config option]

+ 80 - 90
src/main/frontend/components/container.cljs

@@ -168,7 +168,7 @@
   (let [_favorites-updated? (state/sub :favorites/updated?)
         favorite-entities (page-handler/get-favorites)]
     (nav-content-item
-      [:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
+     [:a.flex.items-center.text-sm.font-medium.rounded-md.wrap-th
       (ui/icon "star" {:size 16})
       [:strong.flex-1.ml-2 (string/upper-case (t :left-side-bar/nav-favorites))]]
 
@@ -409,32 +409,32 @@
 
     ;; restore size
     (rum/use-layout-effect!
-      (fn []
-        (when-let [width (storage/get :ls-left-sidebar-width)]
-          (.setProperty (.-style el-doc) "--ls-left-sidebar-width" width)))
-      [])
+     (fn []
+       (when-let [width (storage/get :ls-left-sidebar-width)]
+         (.setProperty (.-style el-doc) "--ls-left-sidebar-width" width)))
+     [])
 
     ;; draggable handler
     (rum/use-effect!
-      (fn []
-        (when-let [el (and (fn? js/window.interact) (rum/deref *el-ref))]
-          (let [^js sidebar-el (.querySelector el-doc "#left-sidebar")]
-            (-> (js/interact el)
-              (.draggable
+     (fn []
+       (when-let [el (and (fn? js/window.interact) (rum/deref *el-ref))]
+         (let [^js sidebar-el (.querySelector el-doc "#left-sidebar")]
+           (-> (js/interact el)
+               (.draggable
                 #js {:listeners
                      #js {:move (fn [^js/MouseEvent e]
                                   (when-let [offset (.-left (.-rect e))]
                                     (let [width (.toFixed (max (min offset 460) 240) 2)]
                                       (adjust-size! (str width "px")))))}})
-              (.styleCursor false)
-              (.on "dragstart" (fn []
-                                 (.. sidebar-el -classList (add "is-resizing"))
-                                 (.. el-doc -classList (add "is-resizing-buf"))))
-              (.on "dragend" (fn []
-                               (.. sidebar-el -classList (remove "is-resizing"))
-                               (.. el-doc -classList (remove "is-resizing-buf"))))))
-          #()))
-      [])
+               (.styleCursor false)
+               (.on "dragstart" (fn []
+                                  (.. sidebar-el -classList (add "is-resizing"))
+                                  (.. el-doc -classList (add "is-resizing-buf"))))
+               (.on "dragend" (fn []
+                                (.. sidebar-el -classList (remove "is-resizing"))
+                                (.. el-doc -classList (remove "is-resizing-buf"))))))
+         #()))
+     [])
     [:span.left-sidebar-resizer {:ref *el-ref}]))
 
 (rum/defcs left-sidebar < rum/reactive
@@ -479,7 +479,7 @@
 
      ;; sidebar contents
      (sidebar-nav route-match close-fn left-sidebar-open? enable-whiteboards? srs-open? *closing?
-       @*close-signal (and touch-pending? touching-x-offset))
+                  @*close-signal (and touch-pending? touching-x-offset))
      ;; resizer
      (sidebar-resizer)]))
 
@@ -724,16 +724,16 @@
   []
 
   (rum/use-effect!
-    (fn []
-      (state/set-state! :ui/handbooks-open? false))
-    [])
+   (fn []
+     (state/set-state! :ui/handbooks-open? false))
+   [])
 
   (rum/use-effect!
-    (fn []
-      (let [h #(state/set-state! :ui/help-open? false)]
-        (.addEventListener js/document.body "click" h)
-        #(.removeEventListener js/document.body "click" h)))
-    [])
+   (fn []
+     (let [h #(state/set-state! :ui/help-open? false)]
+       (.addEventListener js/document.body "click" h)
+       #(.removeEventListener js/document.body "click" h)))
+   [])
 
   [:div.cp__sidebar-help-menu-popup
    [:div.list-wrap
@@ -777,70 +777,61 @@
 
 (rum/defc app-context-menu-observer
   < rum/static
-    (mixins/event-mixin
-      (fn [state]
+  (mixins/event-mixin
+   (fn [state]
         ;; fixme: this mixin will register global event listeners on window
         ;; which might cause unexpected issues
-        (mixins/listen state js/window "contextmenu"
-          (fn [^js e]
-            (let [target (gobj/get e "target")
-                  block-el (.closest target ".bullet-container[blockid]")
-                  block-id (some-> block-el (.getAttribute "blockid"))
-                  {:keys [block block-ref]} (state/sub :block-ref/context)
-                  {:keys [page page-entity]} (state/sub :page-title/context)]
-
-              (let [show!
-                    (fn [content]
-                      (shui/popup-show! e
-                                        (fn [{:keys [id]}]
-                                          [:div {:on-click #(shui/popup-hide! id)
-                                                 :data-keep-selection true}
-                                           content])
-                                        {:on-before-hide state/dom-clear-selection!
-                                         :on-after-hide state/state-clear-selection!
-                                         :content-props {:class "w-[280px] ls-context-menu-content"}
-                                         :as-dropdown? true}))
-
-                    handled
-                    (cond
-                      (and page (not block-id))
-                      (do
-                        (show! (cp-content/page-title-custom-context-menu-content page-entity))
-                        (state/set-state! :page-title/context nil))
-
-                      block-ref
-                      (do
-                        (show! (cp-content/block-ref-custom-context-menu-content block block-ref))
-                        (state/set-state! :block-ref/context nil))
+     (mixins/listen state js/window "contextmenu"
+                    (fn [^js e]
+                      (let [target (gobj/get e "target")
+                            block-el (.closest target ".bullet-container[blockid]")
+                            block-id (some-> block-el (.getAttribute "blockid"))
+                            {:keys [block block-ref]} (state/sub :block-ref/context)
+                            {:keys [page page-entity]} (state/sub :page-title/context)]
+
+                        (let [show!
+                              (fn [content]
+                                (shui/popup-show! e
+                                                  (fn [{:keys [id]}]
+                                                    [:div {:on-click #(shui/popup-hide! id)
+                                                           :data-keep-selection true}
+                                                     content])
+                                                  {:on-before-hide state/dom-clear-selection!
+                                                   :on-after-hide state/state-clear-selection!
+                                                   :content-props {:class "w-[280px] ls-context-menu-content"}
+                                                   :as-dropdown? true}))
+
+                              handled
+                              (cond
+                                (and page (not block-id))
+                                (do
+                                  (show! (cp-content/page-title-custom-context-menu-content page-entity))
+                                  (state/set-state! :page-title/context nil))
+
+                                block-ref
+                                (do
+                                  (show! (cp-content/block-ref-custom-context-menu-content block block-ref))
+                                  (state/set-state! :block-ref/context nil))
 
                       ;; block selection
-                      (and (state/selection?) (not (d/has-class? target "bullet")))
-                      (show! (cp-content/custom-context-menu-content))
+                                (and (state/selection?) (not (d/has-class? target "bullet")))
+                                (show! (cp-content/custom-context-menu-content))
 
                       ;; block bullet
-                      (and block-id (parse-uuid block-id))
-                      (let [block (.closest target ".ls-block")]
-                        (when block
-                          (state/clear-selection!)
-                          (state/conj-selection-block! block :down))
-                        (show! (cp-content/block-context-menu-content target (uuid block-id))))
-
-                      :else
-                      false)]
-                (when (not (false? handled))
-                  (util/stop e))))))))
+                                (and block-id (parse-uuid block-id))
+                                (let [block (.closest target ".ls-block")]
+                                  (when block
+                                    (state/clear-selection!)
+                                    (state/conj-selection-block! block :down))
+                                  (show! (cp-content/block-context-menu-content target (uuid block-id))))
+
+                                :else
+                                false)]
+                          (when (not (false? handled))
+                            (util/stop e))))))))
   []
   nil)
 
-(rum/defc editor-pending-type-block-observer
-  < rum/static rum/reactive
-  []
-  (let [pending-block (state/sub :editor/pending-type-block)
-        editing-block (state/sub :editor/block)]
-    (js/console.warn "FIXME: Apply pending block:" pending-block)
-    [:<>
-     (block/setup-editing-effects editing-block)]))
-
 (rum/defcs ^:large-vars/cleanup-todo root-container <
   (mixins/modal :modal/show?)
   rum/reactive
@@ -917,12 +908,12 @@
 
      [:main.theme-container-inner#app-container-wrapper
       {:class (util/classnames
-                [{:ls-left-sidebar-open left-sidebar-open?
-                  :ls-right-sidebar-open sidebar-open?
-                  :ls-wide-mode wide-mode?
-                  :ls-window-controls window-controls?
-                  :ls-fold-button-on-right fold-button-on-right?
-                  :ls-hl-colored ls-block-hl-colored?}])
+               [{:ls-left-sidebar-open left-sidebar-open?
+                 :ls-right-sidebar-open sidebar-open?
+                 :ls-wide-mode wide-mode?
+                 :ls-window-controls window-controls?
+                 :ls-fold-button-on-right fold-button-on-right?
+                 :ls-hl-colored ls-block-hl-colored?}])
        :on-pointer-up (fn []
                         (when-let [container (gdom/getElement "app-container-wrapper")]
                           (d/remove-class! container "blocks-selection-mode")
@@ -983,7 +974,6 @@
         :nfs-granted? granted?
         :db-restoring? db-restoring?})
       (app-context-menu-observer)
-      (editor-pending-type-block-observer)
 
       [:a#download.hidden]
       (when (and (not config/mobile?)

+ 4 - 1
src/main/frontend/components/editor.cljs

@@ -745,7 +745,10 @@
                   ::ref (atom nil)))
    :did-mount (fn [state]
                 (state/set-editor-args! (:rum/args state))
-                state)}
+                state)
+   :will-unmount (fn [state]
+                   (state/set-state! :editor/raw-mode-block nil)
+                   state)}
   (mixins/event-mixin
    (fn [state]
      (mixins/hide-when-esc-or-outside

+ 6 - 12
src/main/frontend/extensions/code.cljs

@@ -154,11 +154,6 @@
 ;; export CodeMirror to global scope
 (set! js/window -CodeMirror CodeMirror)
 
-(defn- block-render-type-is-code?
-  [block]
-  (some-> block :logseq.property.node/display-type
-          (= :code)))
-
 (defn- all-tokens-by-cursor
   "All tokens from the beginning of the document to the cursor(inclusive)."
   [cm]
@@ -392,16 +387,13 @@
          mode)))))
 
 (defn- save-editor!
-  [^js cm config]
+  [config]
   (p/do!
    (code-handler/save-code-editor!)
    (when-let [block-id (:block/uuid config)]
      (let [block (db/entity [:block/uuid block-id])]
-       (if (block-render-type-is-code? block)
-         (let [block-node (some-> cm (.getTextArea) (.closest ".ls-block"))]
-           ;; select block
-           (util/schedule #(.focus (aget js/window "root-container")))
-           (state/exit-editing-and-set-selected-blocks! [block-node]))
+       (state/set-state! :editor/raw-mode-block block)
+       (when-not (= (:db/id block) (:db/id (state/get-edit-block)))
          (editor-handler/edit-block! block :max))))))
 
 (defn ^:large-vars/cleanup-todo render!
@@ -438,7 +430,7 @@
                            :extraKeys (merge {"Esc" (fn [cm]
                                                       ;; Avoid reentrancy
                                                       (gobj/set cm "escPressed" true)
-                                                      (save-editor! cm config))}
+                                                      (save-editor! config))}
                                              (when config-edit?
                                                {"':'" complete-after
                                                 "Ctrl-Space" "autocomplete"}))}
@@ -481,6 +473,8 @@
                              (vreset! *cursor-curr nil)
                              (vreset! *cursor-prev nil)))
         (.on editor "focus" (fn [_e]
+                              (when-not (= (:block/uuid edit-block) (:block/uuid (state/get-edit-block)))
+                                (editor-handler/edit-block! edit-block :max))
                               (state/set-editing-block-dom-id! (:block-parent-id config))
                               (state/set-block-component-editing-mode! true)
                               (state/set-state! :editor/code-block-context

+ 5 - 3
src/main/frontend/handler/block.cljs

@@ -22,7 +22,8 @@
    [frontend.handler.property.util :as pu]
    [dommy.core :as dom]
    [goog.object :as gobj]
-   [promesa.core :as p]))
+   [promesa.core :as p]
+   [datascript.impl.entity :as de]))
 
 ;;  Fns
 
@@ -177,7 +178,7 @@
                            (state/get-current-editor-container-id)
                            :unknown-container)]
       (state/set-editing! (str "edit-block-" (:block/uuid block)) content block text-range
-        {:container-id container-id :direction direction :event event :pos pos}))
+                          {:container-id container-id :direction direction :event event :pos pos}))
     (mark-last-input-time! repo)))
 
 (defn sanity-block-content
@@ -198,7 +199,8 @@
        (state/clear-edit! {:clear-editing-block? false}))
      (when-let [block-id (:block/uuid block)]
        (let [repo (state/get-current-repo)
-             block (or (db/entity [:block/uuid block-id]) block)
+             block (if (de/entity? block) block
+                       (or (db/entity [:block/uuid block-id]) block))
              content (or custom-content (:block/title block) "")
              content-length (count content)
              text-range (cond

+ 34 - 16
src/main/frontend/handler/events.cljs

@@ -886,6 +886,27 @@
 (defmethod handle :editor/save-code-editor [_]
   (code-handler/save-code-editor!))
 
+(defmethod handle :editor/focus-code-editor [[_ editing-block]]
+  (when (= :code (:logseq.property.node/display-type editing-block))
+    (let [container-id (some-> (:editor/container-id @state/state) (deref))
+          uuid' (:block/uuid editing-block)
+          target (js/document.querySelector
+                  (util/format ".select-language[blockid=\"%s\"][containerid=\"%s\"]" uuid' container-id))]
+      (when-let [^js cm (util/get-cm-instance target)]
+        (when-not (.hasFocus cm)
+          (let [cursor-pos (some-> (:editor/cursor-range @state/state) (deref) (count))
+                direction (:block.editing/direction editing-block)
+                pos (:block.editing/pos editing-block)
+                to-line (case direction
+                          :up (.lastLine cm)
+                          (case pos
+                            :max (.lastLine cm)
+                            0))]
+                 ;; move to friendly cursor
+            (doto cm
+              (.focus)
+              (.setCursor to-line (or cursor-pos 0)))))))))
+
 (defmethod handle :editor/toggle-children-number-list [[_ block]]
   (when-let [blocks (and block (db-model/get-block-immediate-children (state/get-current-repo) (:block/uuid block)))]
     (editor-handler/toggle-blocks-as-own-order-list! blocks)))
@@ -948,23 +969,20 @@
 
 (defmethod handle :editor/upsert-type-block [[_ {:keys [block type]}]]
   (p/do!
-    (editor-handler/save-current-block!)
-    (p/delay 16)
-    (let [block (db/entity (:db/id block))
-          block-type (:logseq.property.node/display-type block)
-          block-title (:block/title block)
-          turn-type! #(db-property-handler/set-block-property!
+   (editor-handler/save-current-block!)
+   (p/delay 16)
+   (let [block (db/entity (:db/id block))
+         block-type (:logseq.property.node/display-type block)
+         block-title (:block/title block)
+         turn-type! #(db-property-handler/set-block-property!
                       (:block/uuid %) :logseq.property.node/display-type (keyword type))]
-      (if (or (not (nil? block-type))
-            (not (string/blank? block-title)))
-        ;; insert block
-        (let [[p _ block'] (editor-handler/insert-new-block-aux! {} block "")]
-          (some-> p
-            (p/then #(turn-type! block'))
-            (p/then #(state/set-pending-type-block! block'))))
-        (-> (turn-type! block)
-          (p/then #(when (string/blank? block-title)
-                     (state/set-pending-type-block! block))))))))
+     (if (or (not (nil? block-type))
+             (not (string/blank? block-title)))
+       ;; insert a new block
+       (let [[p _ block'] (editor-handler/insert-new-block-aux! {} block "")]
+         (some-> p
+                 (p/then #(turn-type! block'))))
+       (turn-type! block)))))
 
 (rum/defc multi-tabs-dialog
   []

+ 100 - 105
src/main/frontend/state.cljs

@@ -164,7 +164,7 @@
       :editor/cursor-range                   (atom nil)
       :editor/container-id                   (atom nil)
       :editor/next-edit-block                (atom nil)
-      :editor/pending-type-block             {}
+      :editor/raw-mode-block                 (atom nil)
 
       :selection/mode                        (atom false)
       ;; Warning: blocks order is determined when setting this attribute
@@ -385,8 +385,8 @@
                       [(<= ?d ?today)]]
              :inputs [:14d :today]
              :result-transform '(fn [result]
-                                 (sort-by (fn [h]
-                                            (get h :block/priority "Z")) result))
+                                  (sort-by (fn [h]
+                                             (get h :block/priority "Z")) result))
              :group-by-page? false
              :collapsed? false}
             {:title "📅 NEXT"
@@ -444,10 +444,10 @@
   (->> configs
        (filter map?)
        (apply merge-with
-         (fn merge-config [current new]
-           (if (and (map? current) (map? new))
-             (merge current new)
-             new)))))
+              (fn merge-config [current new]
+                (if (and (map? current) (map? new))
+                  (merge current new)
+                  new)))))
 
 (defn get-global-config
   []
@@ -483,13 +483,13 @@ should be done through this fn in order to get global config and config defaults
   (or (not @publishing?) (:publishing/enable-editing? (get-config))))
 
 (defonce built-in-macros
-         {"img" "[:img.$4 {:src \"$1\" :style {:width $2 :height $3}}]"})
+  {"img" "[:img.$4 {:src \"$1\" :style {:width $2 :height $3}}]"})
 
 (defn get-macros
   []
   (merge
-    built-in-macros
-    (:macros (get-config))))
+   built-in-macros
+   (:macros (get-config))))
 
 (defn set-assets-alias-enabled!
   [v]
@@ -535,9 +535,9 @@ should be done through this fn in order to get global config and config defaults
    (get-preferred-format (get-current-repo)))
   ([repo-url]
    (keyword
-     (or
-      (common-config/get-preferred-format (get-config repo-url))
-      (get-in @state [:me :preferred_format] "markdown")))))
+    (or
+     (common-config/get-preferred-format (get-config repo-url))
+     (get-in @state [:me :preferred_format] "markdown")))))
 
 (defn markdown?
   []
@@ -547,16 +547,16 @@ should be done through this fn in order to get global config and config defaults
 (defn get-pages-directory
   []
   (or
-    (when-let [repo (get-current-repo)]
-      (:pages-directory (get-config repo)))
-    "pages"))
+   (when-let [repo (get-current-repo)]
+     (:pages-directory (get-config repo)))
+   "pages"))
 
 (defn get-journals-directory
   []
   (or
-    (when-let [repo (get-current-repo)]
-      (:journals-directory (get-config repo)))
-    "journals"))
+   (when-let [repo (get-current-repo)]
+     (:journals-directory (get-config repo)))
+   "journals"))
 
 (defn get-whiteboards-directory
   []
@@ -577,13 +577,13 @@ should be done through this fn in order to get global config and config defaults
 (defn get-preferred-workflow
   []
   (keyword
-    (or
-      (when-let [workflow (:preferred-workflow (get-config))]
-        (let [workflow (name workflow)]
-          (if (util/safe-re-find #"now|NOW" workflow)
-            :now
-            :todo)))
-      (get-in @state [:me :preferred_workflow] :now))))
+   (or
+    (when-let [workflow (:preferred-workflow (get-config))]
+      (let [workflow (name workflow)]
+        (if (util/safe-re-find #"now|NOW" workflow)
+          :now
+          :todo)))
+    (get-in @state [:me :preferred_workflow] :now))))
 
 (defn get-preferred-todo
   []
@@ -602,8 +602,8 @@ should be done through this fn in order to get global config and config defaults
     (if (sqlite-util/db-based-graph? repo)
       (when-let [conn (db-conn-state/get-conn repo)]
         (get (d/entity @conn :logseq.class/Journal)
-           :logseq.property.journal/title-format
-           "MMM do, yyyy"))
+             :logseq.property.journal/title-format
+             "MMM do, yyyy"))
       (common-config/get-date-formatter (get-config)))))
 
 (defn shortcuts []
@@ -627,18 +627,18 @@ should be done through this fn in order to get global config and config defaults
 (defn get-ref-open-blocks-level
   []
   (or
-    (when-let [value (:ref/default-open-blocks-level (get-config))]
-      (when (integer? value)
-        value))
-    2))
+   (when-let [value (:ref/default-open-blocks-level (get-config))]
+     (when (integer? value)
+       value))
+   2))
 
 (defn get-linked-references-collapsed-threshold
   []
   (or
-    (when-let [value (:ref/linked-references-collapsed-threshold (get-config))]
-      (when (integer? value)
-        value))
-    100))
+   (when-let [value (:ref/linked-references-collapsed-threshold (get-config))]
+     (when (integer? value)
+       value))
+   100))
 
 (defn get-export-bullet-indentation
   []
@@ -1464,12 +1464,12 @@ Similar to re-frame subscriptions"
   []
   (when (util/electron?)
     (js/window.apis.setUpdatesCallback
-      (fn [_ args]
-        (let [data (bean/->clj args)
-              pending? (not= (:type data) "completed")]
-          (set-state! :electron/updater-pending? pending?)
-          (when pending? (set-state! :electron/updater data))
-          nil)))))
+     (fn [_ args]
+       (let [data (bean/->clj args)
+             pending? (not= (:type data) "completed")]
+         (set-state! :electron/updater-pending? pending?)
+         (when pending? (set-state! :electron/updater data))
+         nil)))))
 
 (defn set-file-component!
   [component]
@@ -1539,17 +1539,17 @@ Similar to re-frame subscriptions"
            idx (and id (first (keep-indexed #(when (= (:modal/id %2) id) %1)
                                             modals)))
            input (medley/filter-vals
-                   #(not (nil? %1))
-                   {:modal/id            id
-                    :modal/label         (if label (name label) "")
-                    :modal/class         (if center? "as-center" "")
-                    :modal/payload       payload
-                    :modal/show?         (if (boolean? show?) show? true)
-                    :modal/panel-content panel-content
-                    :modal/close-btn?    close-btn?
-                    :modal/close-backdrop? (if (boolean? close-backdrop?) close-backdrop? true)})]
+                  #(not (nil? %1))
+                  {:modal/id            id
+                   :modal/label         (if label (name label) "")
+                   :modal/class         (if center? "as-center" "")
+                   :modal/payload       payload
+                   :modal/show?         (if (boolean? show?) show? true)
+                   :modal/panel-content panel-content
+                   :modal/close-btn?    close-btn?
+                   :modal/close-backdrop? (if (boolean? close-backdrop?) close-backdrop? true)})]
        (swap! state update-in
-         [:modal/subsets (or idx (count modals))]
+              [:modal/subsets (or idx (count modals))]
               merge input)
        (:modal/subsets @state)))))
 
@@ -1564,7 +1564,7 @@ Similar to re-frame subscriptions"
        (if (and id (not (string/blank? mid)) (= id mid))
          (close-modal!)
          (when-let [idx (if id (first (keep-indexed #(when (= (:modal/id %2) id) %1) modals))
-                          (dec (count modals)))]
+                            (dec (count modals)))]
            (swap! state assoc :modal/subsets (into [] (medley/remove-nth idx modals)))))))
    (:modal/subsets @state)))
 
@@ -1640,7 +1640,7 @@ Similar to re-frame subscriptions"
 (defn toggle-left-sidebar!
   []
   (set-left-sidebar-open!
-    (not (get-left-sidebar-open?))))
+   (not (get-left-sidebar-open?))))
 
 (defn set-developer-mode!
   [value]
@@ -1727,7 +1727,7 @@ Similar to re-frame subscriptions"
   (when-let [resource (get-plugin-resource pid type key)]
     (let [resource (assoc resource (keyword attr) val)]
       (set-state!
-        [:plugin/installed-resources (keyword pid) (keyword type) key] resource)
+       [:plugin/installed-resources (keyword pid) (keyword type) key] resource)
       resource)))
 
 (defn get-plugin-services
@@ -1792,8 +1792,8 @@ Similar to re-frame subscriptions"
      (set-state!
       [:plugin/installed-hooks hook]
       (assoc
-        ((fnil identity {}) (get-in @state [:plugin/installed-hooks hook]))
-        pid opts)) true)))
+       ((fnil identity {}) (get-in @state [:plugin/installed-hooks hook]))
+       pid opts)) true)))
 
 (defn uninstall-plugin-hook
   [pid hook-or-all]
@@ -2044,42 +2044,44 @@ Similar to re-frame subscriptions"
           (util/scroll-to-element (gobj/get (first elements) "id")))
         (exit-editing-and-set-selected-blocks! elements))
       (when (and edit-input-id block
-                   (or
-                    (publishing-enable-editing?)
-                    (not @publishing?)))
-          (let [block-element (gdom/getElement (string/replace edit-input-id "edit-block" "ls-block"))
-                container (util/get-block-container block-element)
-                block (if container
-                        (assoc block
-                               :block.temp/container (gobj/get container "id"))
-                        block)
-                block (assoc block :block.editing/direction direction
-                        :block.editing/event event
-                        :block.editing/pos pos)
-                content (string/trim (or content ""))]
-            (assert (and container-id (:block/uuid block))
-                    "container-id or block uuid is missing")
-            (set-state! :editor/block-refs #{})
-            (if property-block
-              (set-editing-block-id! [container-id (:block/uuid property-block) (:block/uuid block)])
-              (set-editing-block-id! [container-id (:block/uuid block)]))
-            (set-state! :editor/container-id container-id)
-            (set-state! :editor/block block)
-            (set-state! :editor/content content :path-in-sub-atom (:block/uuid block))
-            (set-state! :editor/last-key-code nil)
-            (set-state! :editor/set-timestamp-block nil)
-            (set-state! :editor/cursor-range cursor-range)
-
-            (when-let [input (gdom/getElement edit-input-id)]
-              (let [pos (count cursor-range)]
-                (when content
-                  (util/set-change-value input content))
-
-                (when (and move-cursor? (not (block-component-editing?)))
-                  (cursor/move-cursor-to input pos))
-
-                (when (or (util/mobile?) (mobile-util/native-platform?))
-                  (set-state! :mobile/show-action-bar? false)))))))))
+                 (or
+                  (publishing-enable-editing?)
+                  (not @publishing?)))
+        (let [block-element (gdom/getElement (string/replace edit-input-id "edit-block" "ls-block"))
+              container (util/get-block-container block-element)
+              block (if container
+                      (assoc block
+                             :block.temp/container (gobj/get container "id"))
+                      block)
+              block (assoc block :block.editing/direction direction
+                           :block.editing/event event
+                           :block.editing/pos pos)
+              content (string/trim (or content ""))]
+          (assert (and container-id (:block/uuid block))
+                  "container-id or block uuid is missing")
+          (set-state! :editor/block-refs #{})
+          (if property-block
+            (set-editing-block-id! [container-id (:block/uuid property-block) (:block/uuid block)])
+            (set-editing-block-id! [container-id (:block/uuid block)]))
+          (set-state! :editor/container-id container-id)
+          (set-state! :editor/block block)
+          (set-state! :editor/content content :path-in-sub-atom (:block/uuid block))
+          (set-state! :editor/last-key-code nil)
+          (set-state! :editor/set-timestamp-block nil)
+          (set-state! :editor/cursor-range cursor-range)
+
+          (when (= :code (:logseq.property.node/display-type block))
+            (pub-event! [:editor/focus-code-editor block]))
+          (when-let [input (gdom/getElement edit-input-id)]
+            (let [pos (count cursor-range)]
+              (when content
+                (util/set-change-value input content))
+
+              (when (and move-cursor? (not (block-component-editing?)))
+                (cursor/move-cursor-to input pos))
+
+              (when (or (util/mobile?) (mobile-util/native-platform?))
+                (set-state! :mobile/show-action-bar? false)))))))))
 
 (defn action-bar-open?
   []
@@ -2130,10 +2132,10 @@ Similar to re-frame subscriptions"
   ([theme?] (get-enabled?-installed-plugins theme? true false false))
   ([theme? enabled? include-unpacked? include-all?]
    (filterv
-     #(and (if include-unpacked? true (:iir %))
-           (if-not (boolean? enabled?) true (= (not enabled?) (boolean (get-in % [:settings :disabled]))))
-           (or include-all? (if (boolean? theme?) (= (boolean theme?) (:theme %)) true)))
-     (vals (:plugin/installed-plugins @state)))))
+    #(and (if include-unpacked? true (:iir %))
+          (if-not (boolean? enabled?) true (= (not enabled?) (boolean (get-in % [:settings :disabled]))))
+          (or include-all? (if (boolean? theme?) (= (boolean theme?) (:theme %)) true)))
+    (vals (:plugin/installed-plugins @state)))))
 
 (defn lsp-enabled?-or-theme
   []
@@ -2198,7 +2200,6 @@ Similar to re-frame subscriptions"
     (->> (sub :sidebar/blocks)
          (filter #(= (first %) current-repo)))))
 
-
 (defn toggle-collapsed-block!
   [block-id]
   (let [current-repo (get-current-repo)]
@@ -2281,7 +2282,7 @@ Similar to re-frame subscriptions"
   [m]
   (update-state! [:graph/parsing-state (get-current-repo)]
                  (if (fn? m) m
-                   (fn [old-value] (merge old-value m)))))
+                     (fn [old-value] (merge old-value m)))))
 
 (defn http-proxy-enabled-or-val? []
   (when-let [{:keys [type protocol host port] :as agent-opts} (sub [:electron/user-cfgs :settings/agent])]
@@ -2402,12 +2403,6 @@ Similar to re-frame subscriptions"
   []
   (:ui/handbooks-open? @state))
 
-(defn set-pending-type-block!
-  [block]
-  (when block
-    (set-state! :editor/pending-type-block
-      {:block block :at (js/Date.now)})))
-
 (defn get-handbook-route-chan
   []
   (:handbook/route-chan @state))

+ 7 - 0
src/main/frontend/util.cljc

@@ -1536,3 +1536,10 @@ Arg *stop: atom, reset to true to stop the loop"
                 (js->clj)
                 (into {})
                 (walk/keywordize-keys)))))))
+
+#?(:cljs
+   (defn get-cm-instance
+     [^js target]
+     (when target
+       (when-let [node (rec-get-node target "ls-code-editor-wrap")]
+         (some-> node (.querySelector ".CodeMirror") (.-CodeMirror))))))