mirror of https://github.com/logseq/logseq
Introduce keyword :fn to commands
Allows commands to invoke namespaces that previously caused circular dependency issuespull/8524/head
parent
92bec506ec
commit
bcaec408e6
|
@ -58,6 +58,7 @@
|
|||
frontend.handler.common common-handler
|
||||
frontend.handler.common.file file-common-handler
|
||||
frontend.handler.common.plugin plugin-common-handler
|
||||
frontend.handler.common.developer dev-common-handler
|
||||
frontend.handler.config config-handler
|
||||
frontend.handler.events events
|
||||
frontend.handler.global-config global-config-handler
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[frontend.handler.image :as image-handler]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.handler.page :as page-handler]
|
||||
[frontend.handler.common.developer :as dev-common-handler]
|
||||
[frontend.mixins :as mixins]
|
||||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
|
@ -293,7 +294,7 @@
|
|||
(ui/menu-link
|
||||
{:key "(Dev) Show block data"
|
||||
:on-click (fn []
|
||||
(state/pub-event! [:dev/show-entity-data [:block/uuid block-id]]))}
|
||||
(dev-common-handler/show-entity-data [:block/uuid block-id]))}
|
||||
"(Dev) Show block data"
|
||||
nil))
|
||||
|
||||
|
@ -302,7 +303,7 @@
|
|||
{:key "(Dev) Show block AST"
|
||||
:on-click (fn []
|
||||
(let [block (db/pull [:block/uuid block-id])]
|
||||
(state/pub-event! [:dev/show-content-ast (:block/content block) (:block/format block)])))}
|
||||
(dev-common-handler/show-content-ast (:block/content block) (:block/format block))))}
|
||||
"(Dev) Show block AST"
|
||||
nil))])))
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
[frontend.handler.notification :as notification]
|
||||
[frontend.handler.page :as page-handler]
|
||||
[frontend.handler.route :as route-handler]
|
||||
[frontend.handler.common.developer :as dev-common-handler]
|
||||
[frontend.state :as state]
|
||||
[frontend.ui :as ui]
|
||||
[frontend.util :as util]
|
||||
|
@ -162,13 +163,14 @@
|
|||
(when developer-mode?
|
||||
{:title "(Dev) Show page data"
|
||||
:options {:on-click (fn []
|
||||
(state/pub-event! [:dev/show-entity-data (:db/id page)]))}})
|
||||
(dev-common-handler/show-entity-data (:db/id page)))}})
|
||||
|
||||
(when developer-mode?
|
||||
{:title "(Dev) Show page AST"
|
||||
:options {:on-click (fn []
|
||||
(let [page (db/pull '[:block/format {:block/file [:file/content]}] (:db/id page))]
|
||||
(state/pub-event! [:dev/show-content-ast (get-in page [:block/file :file/content])
|
||||
(:block/format page)])))}})]
|
||||
(dev-common-handler/show-content-ast
|
||||
(get-in page [:block/file :file/content])
|
||||
(:block/format page))))}})]
|
||||
(flatten)
|
||||
(remove nil?))))))
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
(ns frontend.handler.common.developer
|
||||
"Common fns for developer related functionality"
|
||||
(:require [frontend.db :as db]
|
||||
[cljs.pprint :as pprint]
|
||||
[frontend.state :as state]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.ui :as ui]
|
||||
[logseq.graph-parser.mldoc :as gp-mldoc]))
|
||||
|
||||
;; Fns used between menus and commands
|
||||
(defn show-entity-data
|
||||
[& pull-args]
|
||||
(let [pull-data (with-out-str (pprint/pprint (apply db/pull pull-args)))]
|
||||
(println pull-data)
|
||||
(notification/show!
|
||||
[:div
|
||||
[:pre.code pull-data]
|
||||
[:br]
|
||||
(ui/button "Copy to clipboard"
|
||||
:on-click #(.writeText js/navigator.clipboard pull-data))]
|
||||
:success
|
||||
false)))
|
||||
|
||||
(defn show-content-ast
|
||||
[content format]
|
||||
(let [ast-data (-> (gp-mldoc/->edn content (gp-mldoc/default-config format))
|
||||
pprint/pprint
|
||||
with-out-str)]
|
||||
(println ast-data)
|
||||
(notification/show!
|
||||
[:div
|
||||
;; Show clipboard at top since content is really long for pages
|
||||
(ui/button "Copy to clipboard"
|
||||
:on-click #(.writeText js/navigator.clipboard ast-data))
|
||||
[:br]
|
||||
[:pre.code ast-data]]
|
||||
:success
|
||||
false)))
|
||||
|
||||
;; Public Commands
|
||||
(defn ^:export show-block-data []
|
||||
;; Use editor state to locate most recent block
|
||||
(if-let [block-uuid (:block-id (first (state/get-editor-args)))]
|
||||
(show-entity-data [:block/uuid block-uuid])
|
||||
(notification/show! "No block found" :error)))
|
||||
|
||||
(defn ^:export show-block-ast []
|
||||
(if-let [{:block/keys [content format]} (:block (first (state/get-editor-args)))]
|
||||
(show-content-ast content format)
|
||||
(notification/show! "No block found" :error)))
|
||||
|
||||
(defn ^:export show-page-data []
|
||||
;; Use editor state to locate most recent page.
|
||||
;; Consider replacing with navigation history if it's more useful
|
||||
(if-let [page-id (get-in (first (state/get-editor-args))
|
||||
[:block :block/page :db/id])]
|
||||
(show-entity-data page-id)
|
||||
(notification/show! "No page found" :error)))
|
||||
|
||||
(defn ^:export show-page-ast []
|
||||
(let [page-data (db/pull '[:block/format {:block/file [:file/content]}]
|
||||
(get-in (first (state/get-editor-args))
|
||||
[:block :block/page :db/id]))]
|
||||
(if (get-in page-data [:block/file :file/content])
|
||||
(show-content-ast (get-in page-data [:block/file :file/content]) (:block/format page-data))
|
||||
(notification/show! "No page found" :error))))
|
|
@ -8,7 +8,6 @@
|
|||
[clojure.core.async.interop :refer [p->c]]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
[cljs.pprint :as pprint]
|
||||
[datascript.core :as d]
|
||||
[frontend.commands :as commands]
|
||||
[frontend.components.diff :as diff]
|
||||
|
@ -66,7 +65,6 @@
|
|||
[promesa.core :as p]
|
||||
[rum.core :as rum]
|
||||
[logseq.graph-parser.config :as gp-config]
|
||||
[logseq.graph-parser.mldoc :as gp-mldoc]
|
||||
[cljs-bean.core :as bean]
|
||||
["@sentry/react" :as Sentry]
|
||||
[frontend.modules.instrumentation.sentry :as sentry-event]))
|
||||
|
@ -921,33 +919,6 @@
|
|||
(when (and command (not (string/blank? content)))
|
||||
(shell-handler/run-cli-command-wrapper! command content)))
|
||||
|
||||
(defmethod handle :dev/show-entity-data [[_ & pull-args]]
|
||||
(let [pull-data (with-out-str (pprint/pprint (apply db/pull pull-args)))]
|
||||
(println pull-data)
|
||||
(notification/show!
|
||||
[:div
|
||||
[:pre.code pull-data]
|
||||
[:br]
|
||||
(ui/button "Copy to clipboard"
|
||||
:on-click #(.writeText js/navigator.clipboard pull-data))]
|
||||
:success
|
||||
false)))
|
||||
|
||||
(defmethod handle :dev/show-content-ast [[_ content format]]
|
||||
(let [ast-data (-> (gp-mldoc/->edn content (gp-mldoc/default-config format))
|
||||
pprint/pprint
|
||||
with-out-str)]
|
||||
(println ast-data)
|
||||
(notification/show!
|
||||
[:div
|
||||
;; Show clipboard at top since content is really long for pages
|
||||
(ui/button "Copy to clipboard"
|
||||
:on-click #(.writeText js/navigator.clipboard ast-data))
|
||||
[:br]
|
||||
[:pre.code ast-data]]
|
||||
:success
|
||||
false)))
|
||||
|
||||
(defn run!
|
||||
[]
|
||||
(let [chan (state/get-events-chan)]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns frontend.modules.shortcut.config
|
||||
(:require [frontend.components.commit :as commit]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.extensions.srs.handler :as srs]
|
||||
[frontend.extensions.pdf.utils :as pdf-utils]
|
||||
[frontend.handler.config :as config-handler]
|
||||
|
@ -19,7 +18,6 @@
|
|||
[frontend.modules.shortcut.dicts :as dicts]
|
||||
[frontend.modules.shortcut.before :as m]
|
||||
[frontend.state :as state]
|
||||
[frontend.db :as db]
|
||||
[frontend.util :refer [mac?] :as util]
|
||||
[frontend.commands :as commands]
|
||||
[frontend.config :as config]
|
||||
|
@ -33,10 +31,14 @@
|
|||
;; almost everywhere else they are not which could cause needless conflicts
|
||||
;; with other config keys
|
||||
|
||||
;; To add a new entry to this map, first add it here and then
|
||||
;; a description for it in frontend.modules.shortcut.dicts/all-default-keyboard-shortcuts.
|
||||
;; :inactive key is for commands that are not active for a given platform or feature condition
|
||||
;; Avoid using single letter shortcuts to allow chords that start with those characters
|
||||
;; To add a new entry to this map, first add it here and then a description for
|
||||
;; it in frontend.modules.shortcut.dicts/all-default-keyboard-shortcuts.
|
||||
;; A shortcut is a map with the following keys:
|
||||
;; * :binding - A string representing a keybinding. Avoid using single letter
|
||||
;; shortcuts to allow chords that start with those characters
|
||||
;; * :fn - Fn or a qualified keyword that represents a fn
|
||||
;; * :inactive - Optional boolean to disable a shortcut for certain conditions
|
||||
;; e.g. a given platform or feature condition
|
||||
(def ^:large-vars/data-var all-default-keyboard-shortcuts
|
||||
;; BUG: Actually, "enter" is registered by mixin behind a "when inputing" guard
|
||||
;; So this setting item does not cover all cases.
|
||||
|
@ -426,7 +428,7 @@
|
|||
:fn plugin-config-handler/open-replace-plugins-modal}
|
||||
|
||||
:ui/clear-all-notifications {:binding false
|
||||
:fn notification/clear-all!}
|
||||
:fn :frontend.handler.notification/clear-all!}
|
||||
|
||||
:editor/toggle-open-blocks {:binding "t o"
|
||||
:fn editor-handler/toggle-open!}
|
||||
|
@ -439,38 +441,19 @@
|
|||
|
||||
:dev/show-block-data {:binding false
|
||||
:inactive (not (state/developer-mode?))
|
||||
:fn (fn []
|
||||
;; Use editor state to locate most recent block
|
||||
(if-let [block-uuid (:block-id (first (state/get-editor-args)))]
|
||||
(state/pub-event! [:dev/show-entity-data [:block/uuid block-uuid]])
|
||||
(notification/show! "No block found" :error)))}
|
||||
:fn :frontend.handler.common.developer/show-block-data}
|
||||
|
||||
:dev/show-block-ast {:binding false
|
||||
:inactive (not (state/developer-mode?))
|
||||
:fn (fn []
|
||||
(if-let [{:block/keys [content format]} (:block (first (state/get-editor-args)))]
|
||||
(state/pub-event! [:dev/show-content-ast content format])
|
||||
(notification/show! "No block found" :error)))}
|
||||
:fn :frontend.handler.common.developer/show-block-ast}
|
||||
|
||||
:dev/show-page-data {:binding false
|
||||
:inactive (not (state/developer-mode?))
|
||||
:fn (fn []
|
||||
;; Use editor state to locate most recent page.
|
||||
;; Consider replacing with navigation history if it's more useful
|
||||
(if-let [page-id (get-in (first (state/get-editor-args))
|
||||
[:block :block/page :db/id])]
|
||||
(state/pub-event! [:dev/show-entity-data page-id])
|
||||
(notification/show! "No page found" :error)))}
|
||||
:fn :frontend.handler.common.developer/show-page-data}
|
||||
|
||||
:dev/show-page-ast {:binding false
|
||||
:inactive (not (state/developer-mode?))
|
||||
:fn (fn []
|
||||
(let [page-data (db/pull '[:block/format {:block/file [:file/content]}]
|
||||
(get-in (first (state/get-editor-args))
|
||||
[:block :block/page :db/id]))]
|
||||
(if (seq page-data)
|
||||
(state/pub-event! [:dev/show-content-ast (get-in page-data [:block/file :file/content]) (:block/format page-data)])
|
||||
(notification/show! "No page found" :error))))}})
|
||||
:fn :frontend.handler.common.developer/show-page-ast}})
|
||||
|
||||
(let [keyboard-shortcuts
|
||||
{::keyboard-shortcuts (set (keys all-default-keyboard-shortcuts))
|
||||
|
@ -479,11 +462,27 @@
|
|||
(str "Keys for keyboard shortcuts must be the same "
|
||||
(data/diff (::keyboard-shortcuts keyboard-shortcuts) (::dicts/keyboard-shortcuts keyboard-shortcuts)))))
|
||||
|
||||
(defn- resolve-fn
|
||||
"Converts a keyword fn to the actual fn. The fn to be resolved needs to be
|
||||
marked as ^:export for advanced mode"
|
||||
[keyword-fn]
|
||||
(fn []
|
||||
(if-let [resolved-fn (some-> (find-ns-obj (namespace keyword-fn))
|
||||
(aget (munge (name keyword-fn))))]
|
||||
(resolved-fn)
|
||||
(throw (ex-info (str "Unable to resolve " keyword-fn " to a fn") {})))))
|
||||
|
||||
(defn build-category-map [ks]
|
||||
(->> (select-keys all-default-keyboard-shortcuts ks)
|
||||
(remove (comp :inactive val))
|
||||
;; Convert keyword fns to real fns
|
||||
(map (fn [[k v]]
|
||||
[k (if (keyword? (:fn v))
|
||||
(assoc v :fn (resolve-fn (:fn v)))
|
||||
v)]))
|
||||
(into {})))
|
||||
|
||||
;; This is the only var that should be publicly expose :fn functionality
|
||||
(defonce ^:large-vars/data-var config
|
||||
(atom
|
||||
{:shortcut.handler/date-picker
|
||||
|
|
Loading…
Reference in New Issue