<commit_before>(ns nightcode.file-browser
  (:require [clojure.java.io :as io]
            [nightcode.dialogs :as dialogs]
            [nightcode.shortcuts :as shortcuts]
            [nightcode.ui :as ui]
            [nightcode.utils :as utils]
            [seesaw.core :as s]
            [seesaw.icon :as icon])
  (:import [java.awt Desktop]
           [javax.swing JLabel SwingConstants]))

(declare update-card!)

(def ^:const tile-size 150)
(def edit-mode? (atom false))

(defn go-up!
  [& _]
  (-> @ui/tree-selection
      io/file
      .getParentFile
      .getCanonicalPath
      ui/update-project-tree!))

(defn create-up-button
  []
  (doto (ui/button :id :up
                   :text "^^"
                   :listen [:action go-up!])
    (s/text! (shortcuts/wrap-hint-text "&uarr;"))
    (utils/set-accessible-name! :parent-directory)))

(defn enter-filename!
  [default-filename]
  (some->> (dialogs/show-text-field-dialog! (utils/get-string :enter-file-name)
                                            default-filename)
           (io/file @ui/tree-selection)))

(defn new-file!
  [& _]
  (when-let [new-file (enter-filename! "example.clj")]
    (if (.exists new-file)
      (dialogs/show-simple-dialog! (utils/get-string :file-exists))
      (do
        (io!
          (.mkdirs (.getParentFile new-file))
          (.createNewFile new-file))
        (ui/update-project-tree! (.getCanonicalPath new-file))))))

(defn edit-files!
  [& _]
  (reset! edit-mode? true)
  (update-card!))

(defn open-in-file-browser!
  [& _]
  (.open (Desktop/getDesktop) (io/file @ui/tree-selection)))

(defn finish-edits!
  [& _]
  (reset! edit-mode? false)
  (update-card!))

(defn save-edits!
  [& _]
  (doseq [tile (s/select @ui/root [:#file-grid :.edit])]
    (let [path (.getName tile)
          f (io/file path)
          fname (some-> (s/select tile [:.name]) first s/text)]
      (cond
        ; delete
        (some-> (s/select tile [:.delete]) first (s/config :selected?))
        (utils/delete-parents-recursively! @ui/tree-projects path)
        ; rename
        (not= (.getName f) fname)
        (io! (.renameTo f (io/file (.getParentFile f) fname))))))
  (ui/update-project-tree!)
  (finish-edits!))

(def ^:dynamic *widgets* [:up :new-file :edit :open-in-browser :save :cancel])

(defn create-actions
  []
  {:up go-up!
   :new-file new-file!
   :edit edit-files!
   :open-in-browser open-in-file-browser!
   :save save-edits!
   :cancel finish-edits!})

(defn create-widgets
  [actions]
  {:up (create-up-button)
   :new-file (ui/button :id :new-file
                        :text (utils/get-string :new-file)
                        :listen [:action (:new-file actions)])
   :edit (ui/button :id :edit
                    :text (utils/get-string :edit)
                    :listen [:action (:edit actions)])
   :open-in-browser (ui/button :id :open-in-browser
                               :text (utils/get-string :open-in-file-browser)
                               :listen [:action (:open-in-browser actions)])
   :save (ui/button :id :save
                    :text (utils/get-string :save)
                    :listen [:action (:save actions)])
   :cancel (ui/button :id :cancel
                      :text (utils/get-string :cancel)
                      :listen [:action (:cancel actions)])})

(defn toggle-visible!
  [view path]
  (let [edit? @edit-mode?
        buttons {:up (and (not edit?)
                          (not (contains? @ui/tree-projects path)))
                 :new-file (not edit?)
                 :edit (and (not edit?)
                            (->> (io/file path)
                                 .listFiles
                                 (filter #(.isFile %))
                                 seq))
                 :open-in-browser (and (not edit?)
                                       (Desktop/isDesktopSupported))
                 :save edit?
                 :cancel edit?}]
    (doseq [btn (s/select view [:#widgets :<javax.swing.JComponent>])]
      (s/config! btn :visible? (get buttons (s/id-of btn) (not edit?))))))

(defn get-icon-path
  [f]
  (when-not (.isDirectory f)
    (case (utils/get-extension (.getName f))
      "clj" "file-clojure.png"
      "cljs" "file-clojure.png"
      "java" "file-java.png"
      "git" "git.png"
      "logcat" nil<commit_msg>Show icon for cljc files<commit_after>(ns nightcode.file-browser
  (:require [clojure.java.io :as io]
            [nightcode.dialogs :as dialogs]
            [nightcode.shortcuts :as shortcuts]
            [nightcode.ui :as ui]
            [nightcode.utils :as utils]
            [seesaw.core :as s]
            [seesaw.icon :as icon])
  (:import [java.awt Desktop]
           [javax.swing JLabel SwingConstants]))

(declare update-card!)

(def ^:const tile-size 150)
(def edit-mode? (atom false))

(defn go-up!
  [& _]
  (-> @ui/tree-selection
      io/file
      .getParentFile
      .getCanonicalPath
      ui/update-project-tree!))

(defn create-up-button
  []
  (doto (ui/button :id :up
                   :text "^^"
                   :listen [:action go-up!])
    (s/text! (shortcuts/wrap-hint-text "&uarr;"))
    (utils/set-accessible-name! :parent-directory)))

(defn enter-filename!
  [default-filename]
  (some->> (dialogs/show-text-field-dialog! (utils/get-string :enter-file-name)
                                            default-filename)
           (io/file @ui/tree-selection)))

(defn new-file!
  [& _]
  (when-let [new-file (enter-filename! "example.clj")]
    (if (.exists new-file)
      (dialogs/show-simple-dialog! (utils/get-string :file-exists))
      (do
        (io!
          (.mkdirs (.getParentFile new-file))
          (.createNewFile new-file))
        (ui/update-project-tree! (.getCanonicalPath new-file))))))

(defn edit-files!
  [& _]
  (reset! edit-mode? true)
  (update-card!))

(defn open-in-file-browser!
  [& _]
  (.open (Desktop/getDesktop) (io/file @ui/tree-selection)))

(defn finish-edits!
  [& _]
  (reset! edit-mode? false)
  (update-card!))

(defn save-edits!
  [& _]
  (doseq [tile (s/select @ui/root [:#file-grid :.edit])]
    (let [path (.getName tile)
          f (io/file path)
          fname (some-> (s/select tile [:.name]) first s/text)]
      (cond
        ; delete
        (some-> (s/select tile [:.delete]) first (s/config :selected?))
        (utils/delete-parents-recursively! @ui/tree-projects path)
        ; rename
        (not= (.getName f) fname)
        (io! (.renameTo f (io/file (.getParentFile f) fname))))))
  (ui/update-project-tree!)
  (finish-edits!))

(def ^:dynamic *widgets* [:up :new-file :edit :open-in-browser :save :cancel])

(defn create-actions
  []
  {:up go-up!
   :new-file new-file!
   :edit edit-files!
   :open-in-browser open-in-file-browser!
   :save save-edits!
   :cancel finish-edits!})

(defn create-widgets
  [actions]
  {:up (create-up-button)
   :new-file (ui/button :id :new-file
                        :text (utils/get-string :new-file)
                        :listen [:action (:new-file actions)])
   :edit (ui/button :id :edit
                    :text (utils/get-string :edit)
                    :listen [:action (:edit actions)])
   :open-in-browser (ui/button :id :open-in-browser
                               :text (utils/get-string :open-in-file-browser)
                               :listen [:action (:open-in-browser actions)])
   :save (ui/button :id :save
                    :text (utils/get-string :save)
                    :listen [:action (:save actions)])
   :cancel (ui/button :id :cancel
                      :text (utils/get-string :cancel)
                      :listen [:action (:cancel actions)])})

(defn toggle-visible!
  [view path]
  (let [edit? @edit-mode?
        buttons {:up (and (not edit?)
                          (not (contains? @ui/tree-projects path)))
                 :new-file (not edit?)
                 :edit (and (not edit?)
                            (->> (io/file path)
                                 .listFiles
                                 (filter #(.isFile %))
                                 seq))
                 :open-in-browser (and (not edit?)
                                       (Desktop/isDesktopSupported))
                 :save edit?
                 :cancel edit?}]
    (doseq [btn (s/select view [:#widgets :<javax.swing.JComponent>])]
      (s/config! btn :visible? (get buttons (s/id-of btn) (not edit?))))))

(defn get-icon-path
  [f]
  (when-not (.isDirectory f)
    (case (utils/get-extension (.getName f))
      "clj" "file-clojure.png"
      "cljc" "file-clojure.png"
      "cljs" "file-clojure.png"
      "java" "file-java.png"
      "git" "git.png"
      "logcat" nil
{'fraction_non_alphanumeric': 0.16065460412584995, 'fraction_numerical': 0.0006914832315316353, 'mean_word_length': 1.811143505021056, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4611526', 'n_tokens_mistral': 2977, 'n_tokens_neox': 2868, 'n_words': 637}