<commit_before>(ns net.sekao.nightcode.shortcuts
  (:require [clojure.string :as str]
            [clojure.set :as set]
            [net.sekao.nightcode.spec :as spec]
            [clojure.spec :as s :refer [fdef]])
  (:import [javafx.scene Node]
           [javafx.scene Scene]
           [javafx.scene.control Tooltip]
           [javafx.scene.input KeyEvent KeyCode]
           [javafx.stage Stage]
           [javafx.event EventHandler]
           [javafx.beans.value ChangeListener]
           [javafx.application Platform]))

(def id->key-char {; project pane
                   :start "p"
                   :import-project "o"
                   :rename "m"
                   :remove "g"
                   :project-tree "↑ ↓ ↲"
                   ; editor pane
                   :up "u"
                   :save "s"
                   :undo "z"
                   :redo "Z"
                   :instarepl "l"
                   :find "f"
                   :close "w"
                   ; build pane
                   :run "r"
                   :run-repl "X"
                   :reload "S"
                   :eval "e"
                   :build "b"
                   :test "t"
                   :stop "i"
                   :build-console "A"
                   ; directory pane
                   :new-file "n"
                   :edit "M"
                   :open-in-browser "F"
                   :cancel "C"})

(def key-char->id (set/map-invert id->key-char))

(fdef keyword->fx-id
  :args (s/cat :k keyword?)
  :ret string?)
(defn keyword->fx-id [k]
  (str "#" (str/replace (name k) #"-" "_")))

(fdef fx-id->keyword
  :args (s/cat :s string?)
  :ret keyword?)
(defn fx-id->keyword [s]
  (-> s (str/replace #"_" "-") keyword))

(fdef add-tooltip!
  :args (s/cat :control spec/node? :text string?))
(defn add-tooltip! [^Node control ^String text]
  (.setTooltip control
    (doto (Tooltip.)
      (.setText text)
      (.setAutoHide false))))

(fdef add-tooltips!
  :args (s/alt
          :nodes (s/cat :nodes (s/coll-of spec/node? []))
          :ids (s/cat :scene spec/scene? :ids (s/coll-of keyword? []))))
(defn add-tooltips!
  ([nodes]
   (doseq [node nodes]
     (when-let [id (.getId node)]
       (when-let [text (get id->key-char (fx-id->keyword id))]
         (add-tooltip! node text)))))
  ([^Scene scene ids]
   (doseq [id ids]
     (let [control (.lookup scene (keyword->fx-id id))
           text (get id->key-char id)]
       (when (and control text)
         (add-tooltip! control text))))))

(fdef show-tooltip!
  :args (s/cat :stage spec/stage? :control spec/node?))
(defn show-tooltip! [^Stage stage ^Node control]
  (when-let [^Tooltip tooltip (.getTooltip control)]
    (let [point (.localToScene control (double 0) (double 0))
          scene (.getScene stage)
          _ (.show tooltip stage (double 0) (double 0))
          half-width (- (/ (.getWidth control) 2)
                        (/ (.getWidth tooltip) 4))
          half-height (- (/ (.getHeight control) 2)
                         (/ (.getHeight tooltip) 4))]
      (.show tooltip stage
        (double (+ (.getX point) (.getX scene) (-> scene .getWindow .getX) half-width))
        (double (+ (.getY point) (.getY scene) (-> scene .getWindow .getY) half-height))))))

(fdef show-tooltips!
  :args (s/cat :stage spec/stage?))
(defn show-tooltips! [^Stage stage]
  (let [scene (.getScene stage)]
    (doseq [id (keys id->key-char)]
      (when-let [control (.lookup scene (keyword->fx-id id))]
        (show-tooltip! stage control)))))

(fdef hide-tooltip!
  :args (s/cat :control spec/node?))
(defn hide-tooltip! [^Node control]
  (some-> control .getTooltip .hide))

(fdef hide-tooltips!
  :args (s/cat :node (s/or :node spec/node? :stage spec/scene?)))
(defn hide-tooltips! [node]
  (doseq [id (keys id->key-char)]
    (when-let [control (.lookup node (keyword->fx-id id))]
      (hide-tooltip! control))))

(fdef run-shortcut!
  :args (s/cat :scene spec/scene? :actions map? :text string? :shift? spec/boolean?))
(defn run-shortcut! [^Scene scene actions ^String text shift?]
  (when-let [id (get key-char->id (if shift? (.toUpperCase text) text))]
    (when-let [action (get actions id)]
      (when-let [widget (some-> scene (.lookup (keyword->fx-id id)))]
        (when (and (not (.isDisabled widget)) (.isManaged widget))
          (Platform/runLater
            (fn []
              (action scene))))))))

(fdef set-shortcut-listeners!
  :args (s/cat :stage spec/stage? :actions map?))<commit_msg>Don't show tooltip on hover<commit_after>(ns net.sekao.nightcode.shortcuts
  (:require [clojure.string :as str]
            [clojure.set :as set]
            [net.sekao.nightcode.spec :as spec]
            [clojure.spec :as s :refer [fdef]])
  (:import [javafx.scene Node]
           [javafx.scene Scene]
           [javafx.scene.control Tooltip]
           [javafx.scene.input KeyEvent KeyCode]
           [javafx.stage Stage]
           [javafx.event EventHandler]
           [javafx.beans.value ChangeListener]
           [javafx.application Platform]))

(def id->key-char {; project pane
                   :start "p"
                   :import-project "o"
                   :rename "m"
                   :remove "g"
                   :project-tree "↑ ↓ ↲"
                   ; editor pane
                   :up "u"
                   :save "s"
                   :undo "z"
                   :redo "Z"
                   :instarepl "l"
                   :find "f"
                   :close "w"
                   ; build pane
                   :run "r"
                   :run-repl "X"
                   :reload "S"
                   :eval "e"
                   :build "b"
                   :test "t"
                   :stop "i"
                   :build-console "A"
                   ; directory pane
                   :new-file "n"
                   :edit "M"
                   :open-in-browser "F"
                   :cancel "C"})

(def key-char->id (set/map-invert id->key-char))

(fdef keyword->fx-id
  :args (s/cat :k keyword?)
  :ret string?)
(defn keyword->fx-id [k]
  (str "#" (str/replace (name k) #"-" "_")))

(fdef fx-id->keyword
  :args (s/cat :s string?)
  :ret keyword?)
(defn fx-id->keyword [s]
  (-> s (str/replace #"_" "-") keyword))

(fdef add-tooltip!
  :args (s/cat :control spec/node? :text string?))
(defn add-tooltip! [^Node control ^String text]
  (.setTooltip control
    (doto (Tooltip.)
      (.setOpacity 0)
      (.setText text))))

(fdef add-tooltips!
  :args (s/alt
          :nodes (s/cat :nodes (s/coll-of spec/node? []))
          :ids (s/cat :scene spec/scene? :ids (s/coll-of keyword? []))))
(defn add-tooltips!
  ([nodes]
   (doseq [node nodes]
     (when-let [id (.getId node)]
       (when-let [text (get id->key-char (fx-id->keyword id))]
         (add-tooltip! node text)))))
  ([^Scene scene ids]
   (doseq [id ids]
     (let [control (.lookup scene (keyword->fx-id id))
           text (get id->key-char id)]
       (when (and control text)
         (add-tooltip! control text))))))

(fdef show-tooltip!
  :args (s/cat :stage spec/stage? :control spec/node?))
(defn show-tooltip! [^Stage stage ^Node control]
  (when-let [^Tooltip tooltip (.getTooltip control)]
    (let [point (.localToScene control (double 0) (double 0))
          scene (.getScene stage)
          _ (.show tooltip stage (double 0) (double 0))
          half-width (- (/ (.getWidth control) 2)
                        (/ (.getWidth tooltip) 4))
          half-height (- (/ (.getHeight control) 2)
                         (/ (.getHeight tooltip) 4))]
      (doto tooltip
        (.setOpacity 1)
        (.show stage
          (double (+ (.getX point) (.getX scene) (-> scene .getWindow .getX) half-width))
          (double (+ (.getY point) (.getY scene) (-> scene .getWindow .getY) half-height)))))))

(fdef show-tooltips!
  :args (s/cat :stage spec/stage?))
(defn show-tooltips! [^Stage stage]
  (let [scene (.getScene stage)]
    (doseq [id (keys id->key-char)]
      (when-let [control (.lookup scene (keyword->fx-id id))]
        (show-tooltip! stage control)))))

(fdef hide-tooltip!
  :args (s/cat :control spec/node?))
(defn hide-tooltip! [^Node control]
  (when-let [tooltip (.getTooltip control)]
    (doto tooltip
      (.setOpacity 0)
      (.hide))))

(fdef hide-tooltips!
  :args (s/cat :node (s/or :node spec/node? :stage spec/scene?)))
(defn hide-tooltips! [node]
  (doseq [id (keys id->key-char)]
    (when-let [control (.lookup node (keyword->fx-id id))]
      (hide-tooltip! control))))

(fdef run-shortcut!
  :args (s/cat :scene spec/scene? :actions map? :text string? :shift? spec/boolean?))
(defn run-shortcut! [^Scene scene actions ^String text shift?]
  (when-let [id (get key-char->id (if shift? (.toUpperCase text) text))]
    (when-let [action (get actions id)]
      (when-let [widget (some-> scene (.lookup (keyword->fx-id id)))]
        (when (and (not (.isDisabled widget)) (.isManaged widget))
          (Platform/runLater
            (fn []
              (action scene))))))))

(fdef set-shortcut-listeners!
  :args (s/cat :stage spec/stage? :actions map?))
{'fraction_non_alphanumeric': 0.16183072374904195, 'fraction_numerical': 0.0020803678966385634, 'mean_word_length': 1.8463695855406668, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1442072', 'n_tokens_mistral': 3135, 'n_tokens_neox': 2946, 'n_words': 823}