浏览代码

enhance(plugin): plugin settings for web lsp

charlie 9 月之前
父节点
当前提交
9ce4bbc16c

+ 4 - 2
libs/src/LSPlugin.core.ts

@@ -98,11 +98,13 @@ class PluginSettings extends EventEmitter<'change' | 'reset'> {
       return
     }
 
-    this.emit('change', Object.assign({}, this._settings), o)
+    this.emit('change', { ...this._settings }, o)
   }
 
   set settings(value: Record<string, any>) {
-    this._settings = value
+    const o = deepMerge({}, this._settings)
+    this._settings = value || {}
+    this.emit('change', { ...this._settings }, o)
   }
 
   get settings(): Record<string, any> {

文件差异内容过多而无法显示
+ 0 - 0
resources/js/lsplugin.core.js


+ 2 - 1
src/main/frontend/components/plugins.cljs

@@ -249,7 +249,8 @@
      [:strong (ui/icon "settings")]
      [:ul.menu-list
       [:li {:on-click #(plugin-handler/open-plugin-settings! id false)} (t :plugin/open-settings)]
-      [:li {:on-click #(js/apis.openPath url)} (t :plugin/open-package)]
+      (when (util/electron?)
+        [:li {:on-click #(js/apis.openPath url)} (t :plugin/open-package)])
       [:li {:on-click #(plugin-handler/open-report-modal! id name)} (t :plugin/report-security)]
       [:li {:on-click
             #(-> (shui/dialog-confirm!

+ 13 - 9
src/main/frontend/components/plugins.css

@@ -457,25 +457,29 @@
 
   &-settings {
     &-inner {
-      position: relative;
-      padding: 10px 0 20px;
+      @apply relative pt-2.5 pb-5 px-0;
 
       > .edit-file {
-        position: absolute;
-        top: 12px;
-        right: 8px;
+        @apply absolute top-3 right-2;
+      }
+
+      &[data-mode=code] {
+        @apply pt-2;
+
+        > .edit-file {
+          @apply -top-3.5;
+        }
       }
 
       .heading-item {
-        margin: 12px 12px 6px;
-        border-bottom: 1px solid var(--ls-border-color, #738694);
+        @apply pt-3 px-3 pb-1.5 border-b;
 
         h2 {
-          font-weight: bold;
+          @apply font-bold;
         }
 
         small:empty {
-          display: none;
+          @apply hidden;
         }
       }
 

+ 65 - 26
src/main/frontend/components/plugins_settings.cljs

@@ -1,8 +1,11 @@
 (ns frontend.components.plugins-settings
-  (:require [rum.core :as rum]
+  (:require [logseq.shui.ui :as shui]
+            [rum.core :as rum]
             [frontend.util :as util]
             [frontend.ui :as ui]
             [frontend.handler.plugin :as plugin-handler]
+            [frontend.components.lazy-editor :as lazy-editor]
+            [frontend.handler.notification :as notification]
             [cljs-bean.core :as bean]
             [goog.functions :refer [debounce]]))
 
@@ -19,11 +22,16 @@
    {:dangerouslySetInnerHTML {:__html (dom-purify html nil)}}])
 
 (rum/defc edit-settings-file
-  [pid {:keys [class]}]
+  [pid {:keys [class edit-mode set-edit-mode!]}]
   [:a.text-sm.hover:underline
    {:class    class
-    :on-click #(plugin-handler/open-settings-file-in-default-app! pid)}
-   "Edit settings.json"])
+    :on-click (fn []
+                (if (util/electron?)
+                  (plugin-handler/open-settings-file-in-default-app! pid)
+                  (set-edit-mode! #(if % nil :code))))}
+   (if (= edit-mode :code)
+     "Exit code mode"
+     "Edit settings.json")])
 
 (rum/defc render-item-input
   [val {:keys [key type title default description inputAs]} update-setting!]
@@ -89,7 +97,8 @@
 
    [:div.form-control
     (html-content description)
-    [:div.pl-1 (edit-settings-file pid nil)]]])
+    (when (util/electron?)
+      [:div.pl-1 (edit-settings-file pid nil)])]])
 
 (rum/defc render-item-heading
   [{:keys [key title description]}]
@@ -107,14 +116,15 @@
   [schema ^js pl]
   (let [^js plugin-settings (.-settings pl)
         pid (.-id pl)
-        [settings, set-settings] (rum/use-state (bean/->clj (.toJSON plugin-settings)))
+        [settings, set-settings!] (rum/use-state (bean/->clj (.toJSON plugin-settings)))
+        [edit-mode, set-edit-mode!] (rum/use-state nil) ;; code
         update-setting! (fn [k v] (.set plugin-settings (name k) (bean/->js v)))]
 
     (rum/use-effect!
      (fn []
        (let [on-change (fn [^js s]
                          (when-let [s (bean/->clj s)]
-                           (set-settings s)))]
+                           (set-settings! s)))]
          (.on plugin-settings "change" on-change)
          #(.off plugin-settings "change" on-change)))
      [pid])
@@ -123,27 +133,56 @@
       [:<>
        [:h2.text-xl.px-2.pt-1.opacity-90 "ID: " pid]
        [:div.cp__plugins-settings-inner
+        {:data-mode (some-> edit-mode (name))}
         ;; settings.json
         [:span.edit-file
-         (edit-settings-file pid nil)]
-
-        ;; render items
-        (for [desc schema
-              :let [key (:key desc)
-                    val (get settings (keyword key))
-                    type (keyword (:type desc))
-                    desc (update desc :description #(plugin-handler/markdown-to-html %))]]
-
-          (rum/with-key
-            (condp contains? type
-              #{:string :number} (render-item-input val desc update-setting!)
-              #{:boolean} (render-item-toggle val desc update-setting!)
-              #{:enum} (render-item-enum val desc update-setting!)
-              #{:object} (render-item-object val desc pid)
-              #{:heading} (render-item-heading desc)
-
-              (render-item-not-handled key))
-            key))]]
+         (edit-settings-file pid {:set-edit-mode! set-edit-mode!
+                                  :edit-mode edit-mode})]
+
+        (if (= edit-mode :code)
+          ;; render with code editor
+          [:div.code-mode-wrap.pl-3.py-1.mb-8
+           (let [content' (js/JSON.stringify (bean/->js settings) nil 2)]
+             (lazy-editor/editor {:file? false}
+               (str "code-edit-lsp-settings")
+               {:data-lang "json"}
+               content' {}))
+           [:div.flex.justify-end.pt-2.gap-2
+            (shui/button {:size :sm :variant :ghost
+                          :on-click (fn [^js e]
+                                      (let [^js cm (util/get-cm-instance (-> (.-target e) (.closest ".code-mode-wrap")))
+                                            content' (some-> (.toJSON plugin-settings) (js/JSON.stringify nil 2))]
+                                        (.setValue cm content')))}
+              "Reset")
+            (shui/button {:size :sm
+                          :on-click (fn [^js e]
+                                      (try
+                                        (let [^js cm (util/get-cm-instance (-> (.-target e) (.closest ".code-mode-wrap")))
+                                              content (.getValue cm)
+                                              content' (js/JSON.parse content)]
+                                          (set! (. plugin-settings -settings) content')
+                                          (set-edit-mode! nil))
+                                        (catch js/Error e
+                                          (notification/show! (.-message e) :error))))}
+              "Save")]]
+
+          ;; render with gui items
+          (for [desc schema
+                :let [key (:key desc)
+                      val (get settings (keyword key))
+                      type (keyword (:type desc))
+                      desc (update desc :description #(plugin-handler/markdown-to-html %))]]
+
+            (rum/with-key
+              (condp contains? type
+                #{:string :number} (render-item-input val desc update-setting!)
+                #{:boolean} (render-item-toggle val desc update-setting!)
+                #{:enum} (render-item-enum val desc update-setting!)
+                #{:object} (render-item-object val desc pid)
+                #{:heading} (render-item-heading desc)
+
+                (render-item-not-handled key))
+              key)))]]
 
       ;; no settings
       [:h2.font-bold.text-lg.py-4.warning "No Settings Schema!"])))

部分文件因为文件数量过多而无法显示