;;; gui-settings --- Summary

;;; Commentary:

;;; Requirements:
;; restart-emacs https://melpa.org/#/restart-emacs
;; dashboard https://melpa.org/#/dashboard
;;   page-break-lines https://melpa.org/#/page-break-lines
;;   all-the-icons https://melpa.org/#/all-the-icons
;;     memoize https://melpa.org/#/memoize
;; indent-guide https://melpa.org/#/indent-guide
;; not highlight-indent-guides
;; rainbow-mode https://elpa.gnu.org/packages/rainbow-mode.html
;; focus https://melpa.org/#/focus
;; virtual-auto-fill https://melpa.org/#/virtual-auto-fill

;;; Code:

;; defining characters, e.g. vertical bar │:
;; - 9474     as decimal
;; - #o22402  as octal
;; - #x2502   as unicode
;; using characters inside string:
;; - "\u2502"

(use-package emacs
  :delight
  (auto-fill-function "Fa")              ;; "\u21B5"
  (compilation-shell-minor-mode "Csh")   ;; "\u24B8\uFF53"
  (eldoc-mode "Ed")                      ;; "\u24BA" e
  (visual-line-mode "Vl")                ;; " Wrap" "\u21A9"
  (whitespace-mode "Ws")                 ;; "\u2423 \u005F ws"
  ;; major modes
  (calendar-mode "Ca")                   ;; "Calendar" "\u01F4C6" "\u01F152\uFF41\uFF4C"
  (css-mode "Css")                       ;; "CSS"" "\u01F152ss
  (emacs-lisp-mode "El")                 ;; "EL" "\u01F15B\uFF45"
  (eshell-mode "Esh")                    ;; "Esh" "\u01F162\uFF45
  (fundamental-mode "Fu")                ;; "F " "\u01F155" ;; not working
  (help-mode "H")                        ;; "H " "\u01F157"
  (Info-mode "I")                        ;; "I " "\u01F158" ;; not working
  (latex-mode "La")                      ;; "LaTeX " "\u01F15B\uFF41"
  (lisp-interaction-mode "Lii")          ;; "LI \u01F15B\u24A4" "\u01F15B\uFF49
  (messages-mode "M")                    ;; "M " "\u01F15C"  ;; not working
  (messages-buffer-mode "M")             ;; "M " "\u01F15C"  ;; not working
  (inferior-python-mode "Pyi")           ;; "IPy \u01F15F\u24A4" "\u01F15F\uFF49"
  :hook
  (prog-mode . display-fill-column-indicator-mode)
  (help-mode . visual-line-mode)
  (messages-buffer-mode . visual-line-mode)
  :config
  ;; display-fill-column-indicator
  ;; (setq display-fill-column-indicator-character 9474)  ;; 9474 is default
  (set-face-attribute 'fill-column-indicator nil :foreground "DarkSlateGray"))


;;          ┌────────────── Frame width ───────────────┐
;;                  ┌────── Window width ──────┐
;;   ┌      ┌──────────────────────────────────────────┐
;;   │      │ ┌──────────────────────────────────────┐ │
;;   │      │ │              Header line             │ │
;;   │    ┌ │ ├───┬─┬────────────────────────┬─┬─┬───┤ │
;; F │  W │ │ │   │●┼─ Left fringe           ┊ │ │   │●┼── Frame border 
;; r │  i │ │ │ ●─┼─┼─ Left margin           ┊ │ │ ●─┼─┼── Right margin 
;; a │  n │ │ │   │ │                        ┊ │●┼───┼─┼── Right fringe 
;; m │  d │ │ │   │ │                        ┊●┼─┼───┼─┼── Display column
;; e │  o │ │ │   │ │                        ┊ │ │   │ │
;;   │  w │ │ │   │ │                        ┊ │ │   │ │
;; h │    │ │ │   │ │         Text area      ┊ │ │   │ │
;; e │  h │ │ │   │ │                        ┊ │ │   │ │
;; i │  e │ │ │   │ │                        ┊ │ │   │ │
;; g │  i │ │ │   │ │                        ┊ │ │   │ │
;; h │  g │ │ │   │ │                        ┊ │ │   │ │
;; t │  h │ │ │   │ │                        ┊ │ │   │ │
;;   │  t │ │ │   │ │                        ┊ │ │   │ │
;;   │    └ │ ├───┴─┴────────────────────────┴─┴─┴───┤ │
;;   │      │ │               Mode line              │ │
;;   │      │ ├───┬─┬──────────────────────────┬─┬───┤ │
;;   │      │ │   │ │  Minibuffer / Echo area  │ │   │ │ 
;;   │      │ └───┴─┴──────────────────────────┴─┴───┘ │
;;   └      └──────────────────────────────────────────┘
;;            └─┬─┘                            └┬┘   └┬┘
;;         Margin width   Fringe width (pixels) ┘     │
;;           (chars)            Border width (pixels) ┘
(use-package frame
  :config
  (setq window-divider-default-right-width 2)
  ;; (setq window-divider-default-bottom-width 1)  ;; -2 from awesome-tray
  (setq window-divider-default-places 'right-only)
  (window-divider-mode 1))

(use-package scroll-bar
  ;; built-in
  :defer t
  :config
  ;; `scroll-bar-mode' sets for all frames and all windows
  ;; use `set-window-scroll-bars' for windows only
  (scroll-bar-mode 0)  ;; 1st deactivate scrolling
  (defun my-window-scroll-function (window display-start)
    "This function
- is listed in `window-scroll-functions' which is called by
  `set-window-buffer' before running `window-configuration-change-hook'
  and therefore will be run on every vertical scroll event
- will activate vertical scoll bar if not whole buffer height is
  visible

WINDOW: `window' object, its string will look like #<window 3 on gui-settings.el> and
DISPLAY-START: `integer', e.g. 3820"
    ;; (message "%s" window)
    (let ((vertical-type nil)
          (horizontal-type nil))
      (unless (string-equal (format-mode-line "%p") "All")
        (setq vertical-type 'right))
      ;; `scroll-bar-mode' not used bc/ it's global, therefore:
      (set-window-scroll-bars
       window nil vertical-type nil horizontal-type nil)))
  (add-to-list 'window-scroll-functions #'my-window-scroll-function))

(use-package tab-bar
  :bind ((:map global-map
               (("s-{" . tab-bar-switch-to-prev-tab)
                ("s-}" . tab-bar-switch-to-next-tab)
                ("s-t" . tab-bar-new-tab)
                ("s-w" . tab-bar-close-tab))))
  :config
  ;; add menu button
  (add-to-list 'tab-bar-format #'tab-bar-format-menu-bar)
  
  ;; add tool bar
  (require 'my-tool-bar)
  (add-to-list 'tab-bar-format #'my-tool-bar-format)

  (tab-bar-rename-tab "Default")
  (defun my-tab-view-elisp ()
    (if (tab-bar--tab-index-by-name "ELisp IDE")
        (tab-bar-switch-to-tab "ELisp IDE")
      (tab-bar-new-tab)
      (tab-bar-rename-tab "ELisp IDE")
      (switch-to-buffer "*scratch*")
      (my-view-elisp)))
  (defun my-tab-view-python ()
    (if (tab-bar--tab-index-by-name "Python IDE")
        (tab-bar-switch-to-tab "Python IDE")
      (tab-bar-new-tab)
      (tab-bar-rename-tab "Python IDE")
      (if (get-buffer "*scratch-python*")
          (switch-to-buffer "*scratch-python*")
        (switch-to-buffer "*scratch-python*")
        (insert "#!/usr/bin/env python\n")
        (insert "\"\"\"\n")
        (insert "\"\"\"\n"))
      (python-mode)
      (my-view-python)))
  (defun my-tab-view-shell ()
    (if (tab-bar--tab-index-by-name "Shell IDE")
        (tab-bar-switch-to-tab "Shell IDE")
      (tab-bar-new-tab)
      (tab-bar-rename-tab "Shell IDE")
      (switch-to-buffer "*scratch-shell*")
      (shell-script-mode)
      (my-view-shell)))
  (defun my-tab-view-org-pdf ()
    (if (tab-bar--tab-index-by-name "Org PDF")
        (tab-bar-switch-to-tab "Org PDF")
      (tab-bar-new-tab)
      (tab-bar-rename-tab "Org PDF")
      (switch-to-buffer "*scratch-org*")
      (org-mode)
      (my-view-org-pdf)))
  (defun my-tab-view-gnuplot ()
    (if (tab-bar--tab-index-by-name "Gnuplot IDE")
        (tab-bar-switch-to-tab "Gnuplot IDE")
      (tab-bar-new-tab)
      (tab-bar-rename-tab "Gnuplot IDE")
      (switch-to-buffer "*scratch-gnuplot*")
      (gnuplot-mode)
      (my-view-gnuplot))))

(use-package awesome-tray
  :defer nil
  :after my-theme
  :hook (after-init . awesome-tray-mode)
  :init (setq mode-line-format nil)
  :config
  (setq awesome-tray-info-padding-right 1)
  (setq awesome-tray-buffer-name-buffer-changed t)
  (setq awesome-tray-mode-line-active-color "#008b8b")
  (setq awesome-tray-mode-line-inactive-color "#333333")
  (setq awesome-tray-file-path-show-filename nil)
  (setq awesome-tray-file-path-truncated-name-length 2)
  (setq awesome-tray-file-path-full-dirname-levels 2)

  ;; flycheck custom string
  (defun my-awesome-tray-module-flycheck-info ()
    (let ((flycheck-mode-line-prefix "fc"))
      (string-trim (flycheck-mode-line-status-text))))

  ;; flycheck color string
  (defface my-awesome-tray-module-flycheck-face
    (list (list t (list :foreground (face-foreground 'font-lock-warning-face))))
    "Flycheck module face."
    :group 'awesome-tray)

  ;; flycheck add as module
  (add-to-list 'awesome-tray-module-alist
               '("flycheck" . (my-awesome-tray-module-flycheck-info my-awesome-tray-module-flycheck-face)))

  ;; flymake custom string
  (defun my-awesome-tray-module-flymake-info ()
    "A module for showing Flymake state."
    ;; Parts of the code are from doom-modeline package
    (with-demoted-errors
        ""
      (if (and (featurep 'flymake) flymake--state)
          (let* ((known (hash-table-keys flymake--state))
                 (running (flymake-running-backends))
                 (disabled (flymake-disabled-backends))
                 (reported (flymake-reporting-backends))
                 (disabledp (and disabled (null running)))
                 (waiting (cl-set-difference running reported)))
            (when-let
                ((flymake-state
                  (cond
                   (waiting "*")
                   ;;(waiting "⏳")
                   ((null known) "❔")
                   (disabledp "❕")
                   (t (let ((.error 0)
                            (.warning 0)
                            (.note 0))
                        (cl-loop
                         with warning-level = (warning-numeric-level :warning)
                         with note-level = (warning-numeric-level :debug)
                         for state being the hash-values of flymake--state
                         do (cl-loop
                             with diags = (flymake--state-diags state)
                             for diag in diags do
                             (let ((severity (flymake--lookup-type-property (flymake--diag-type diag) 'severity
                                                                            (warning-numeric-level :error))))
                               (cond ((> severity warning-level) (cl-incf .error))
                                     ((> severity note-level)    (cl-incf .warning))
                                     (t                          (cl-incf .note))))))
                        (let ((num (+ .error .warning .note)))
                          (if (> num 0)
                              (string-clean-whitespace
                               (string-join
                                (list
                                 (when (>= .error 0)
                                   ;; "🔴:"
                                   (concat "" (propertize (number-to-string .error) 'face 'awesome-tray-module-flymake-error)))
                                 (when (>= .warning 0)
                                   ;; "🟠:"
                                   (concat "" (propertize (number-to-string .warning) 'face 'awesome-tray-module-flymake-warning)))
                                 (when (>= .note 0)
                                   ;; "🔵:"
                                   (concat "" (propertize (number-to-string .note) 'face 'awesome-tray-module-flymake-note)))
                                 )
                                ":" ;; " " joining string
                                ))
                            "" ;; "🟢" no error/warning/note
                            )))))))
              flymake-state)))))

  ;; flycheck add as module
  ;; (add-to-list 'awesome-tray-module-alist
  ;;              '("flymake" . (my-awesome-tray-module-flymake-info nil)))
  (add-to-list 'awesome-tray-module-alist
               '("flymake" . (my-awesome-tray-module-flymake-info my-awesome-tray-module-flycheck-face)))

  ;; doc-view custom string
  (defun my-awesome-tray-module-doc-view-page-info ()
    (with-demoted-errors
        ""
      (cond
       ((and (derived-mode-p 'eaf-mode)
             (string-equal eaf--buffer-app-name "pdf-viewer"))
        (eaf-call-sync "execute_function" eaf--buffer-id "get_progress"))
       ((featurep 'pdf-view)
        (let ((state
               (cond ((derived-mode-p 'pdf-view-mode) (format "%d/%d" (eval '(pdf-view-current-page)) (pdf-cache-number-of-pages)))
                     (t ""))))
          state))
       ((featurep 'doc-view)
        (let ((state
               (cond ((derived-mode-p 'doc-view-mode) (format "%d/%d" (eval '(doc-view-current-page)) (doc-view-last-page-number)))
                     (t ""))))
          state))
       (t ""))))
  (defun my-awesome-tray-module-location-or-page-info ()
    "Show Location or PDF page depends on current mode."
    (let ((page-info (my-awesome-tray-module-doc-view-page-info)))
      (if (string= page-info "")
          (awesome-tray-module-location-info)
        page-info)))

  ;; doc-view add as module
  (add-to-list 'awesome-tray-module-alist
               '("location-or-page" . (my-awesome-tray-module-location-or-page-info awesome-tray-module-location-face)))
  
  ;; see available modules in `awesome-tray-module-alist'
  (setq awesome-tray-active-modules
    '("file-path"
      "buffer-name"
      "buffer-read-only"
      ;; "location"
      "location-or-page"
      "mode-name"
      "flycheck"
      "flymake"
      "git"))
  (set-face-foreground 'awesome-tray-module-file-path-face (face-foreground 'font-lock-keyword-face))
  (set-face-foreground 'awesome-tray-module-buffer-name-face (face-foreground 'font-lock-constant-face))
  (set-face-foreground 'awesome-tray-module-location-face (face-foreground 'vertical-border))
  (set-face-foreground 'awesome-tray-module-location-or-page-face (face-foreground 'vertical-border))
  (set-face-foreground 'awesome-tray-module-mode-name-face (face-foreground 'font-lock-string-face))
  (defun my-awesome-tray-module-file-path-info-advice (&rest args)
    "If file path is same as buffer name omit output."
    (if (string= (car args) (awesome-tray-module-buffer-name-info))
        ""
      (car args)))
  (advice-add 'awesome-tray-module-file-path-info :filter-return #'my-awesome-tray-module-file-path-info-advice)
  ;; old `awesome-tray-module-buffer-name-info'. new one breaks some org-mod src block return actions.
  (defun awesome-tray-module-buffer-name-info ()
    (if awesome-tray-buffer-name-buffer-changed
        (if (and (buffer-modified-p)
                 (not (eq buffer-file-name nil)))
            (concat (buffer-name) awesome-tray-buffer-name-buffer-changed-style)
          (buffer-name))
      (format "%s" (buffer-name))))
  )

(use-package doc-view
  :defer t
  :delight (doc-view-mode "Doc")  ;; "DocView" "\u01F153\uFF4F\uFF43"
  :config
  (setq doc-view-continuous t))

(use-package restart-emacs
  :commands (restart-emacs restart-emacs-start-new-emacs))

(use-package page-break-lines
  :delight (page-break-lines-mode "Pb")  ;; "\u24C5\uFF42"
  :config
  (add-to-list 'page-break-lines-modes 'python-mode)
  (add-to-list 'page-break-lines-modes 'ledger-mode)
  (add-to-list 'page-break-lines-modes 'dashboard-mode)
  (global-page-break-lines-mode 1))

(use-package memoize
  :defer t)

(use-package all-the-icons
  :defer t
  :if (display-graphic-p)
  :config
  (when (and (not (my-font-installed-p "all-the-icons"))
             (window-system))
    (all-the-icons-install-fonts t)
    ;;(restart-emacs)  ;; infinity loop?
    ))

(use-package dashboard
  :defer nil
  :delight (dashboard-mode "Db")  ;; "\u01F153"
  :commands (dashboard-mode)
  :config
  ;; see `dashboad-widget'
  (setq dashboard-banner-logo-title
        (format "Welcome to Emacs! (%s — %s"
                emacs-version
                (when (and (fboundp 'native-comp-available-p)
                           (native-comp-available-p))
                  "with native compilation)")))
  (setq dashboard-icon-type 'all-the-icons)
  (setq dashboard-page-separator "\n\f\n")
  (setq dashboard-set-heading-icons t)
  (setq dashboard-set-file-icons t)
  (setq dashboard-set-navigator t)
  (setq dashboard-startup-banner 'logo)
  (setq dashboard-heading-icons '((recents   . "history")
                                  (bookmarks . "bookmark")
                                  (agenda    . "calendar")
                                  (projects  . "rocket")
                                  (registers . "database")
                                  (custom    . "versions")
                                  ))
  (setq dashboard-startupify-list
        '(dashboard-insert-banner
          dashboard-insert-newline
          dashboard-insert-banner-title
          dashboard-insert-newline
          dashboard-insert-init-info
          dashboard-insert-newline
          dashboard-insert-newline
          dashboard-insert-navigator
          dashboard-insert-items
          dashboard-insert-newline
          dashboard-insert-footer))
  (setq dashboard-items '((recents   . 10) ;; slow
                          (bookmarks . 5)
                          ;; (projects  . 5)  ;; projectile or project.el
                          ;; (agenda    . 5)  ;; will open org file (requires org-mode etc.)
                          (registers . 5)
                          (custom    . 5)
                          ))
  (setq dashboard-item-shortcuts
        '((recents   . "r")
          (bookmarks . "m")
          (projects  . "p")
          (agenda    . "a")
          (registers . "e")
          (custom    . "b")))

  (if (display-graphic-p)
      (let ()
        (require 'all-the-icons)
        (setq dashboard-navigator-buttons
              ;; list of lines having list of elements
              ;; element: (icon title help action face prefix suffix)
              ;;  |------------------------- icon --------------------------------------|---- title ----|------ help ---------|------------- action ---------------------------------------|-face--|prefix|suffix|
              `(;; 1st line custom views
                ((""                                                                     ""              "space"               nil                                                          default "" "")
                 (""                                                                     "Custom Views:" "custom views"        nil                                                          default "" "")
                 (,(all-the-icons-fileicon   "elisp"        :height 1.0 :v-adjust -0.1)  "ELisp"         "my-view-elisp"       (lambda (&rest _) (my-tab-view-elisp))                       dashboard-navigator "" "")
                 (,(all-the-icons-alltheicon "python"       :height 1.0 :v-adjust 0.0)   "Python"        "my-view-python"      (lambda (&rest _) (my-tab-view-python))                      dashboard-navigator "" "")
                 (,(all-the-icons-alltheicon "script"       :height 1.0 :v-adjust 0.0)   "Shell"         "my-view-shell"       (lambda (&rest _) (my-tab-view-shell))                       dashboard-navigator "" "")
                 (,(all-the-icons-octicon    "file-media"   :height 1.0 :v-adjust 0.0)   "Gnuplot"       "my-view-gnuplot"     (lambda (&rest _) (my-tab-view-gnuplot))                     dashboard-navigator "" "")
                 (,(all-the-icons-octicon    "file-pdf"     :height 1.0 :v-adjust 0.0)   "Org-PDF"       "my-view-org-pdf"     (lambda (&rest _) (my-tab-view-org-pdf))                     dashboard-navigator "" "")
                 )
                ;; 2nd line major modes 1st part
                ((""                                                                     ""              "space"               nil                                                          default "" "")
                 (""                                                                     "Major Modes:"  "major modes"         nil                                                          default "" "")
                 (""                                                                     "Deft"          "deft"                (lambda (&rest _) (deft))                                    dashboard-navigator "" "")
                 (""                                                                     "EShell"        "eshell-mode"         (lambda (&rest _) (eshell))                                  dashboard-navigator "" "")
                 (""                                                                     "Magit"         "magit"               (lambda (&rest _) (magit))                                   dashboard-navigator "" "")
                 (,(all-the-icons-octicon    "mail"         :height 1.0 :v-adjust 0.0)   "Mu4e"          "mu4e"                (lambda (&rest _) (mu4e))                                    dashboard-navigator "" "")
                 (,(all-the-icons-octicon    "mail"         :height 1.0 :v-adjust 0.0)   "Notmuch"       "notmuch"             (lambda (&rest _) (notmuch))                                 dashboard-navigator "" "")
                 (""                                                                     "Org-Brain"     "org-brain-visualize" (lambda (&rest _) (call-interactively 'org-brain-visualize)) dashboard-navigator "" "")
                 )
                ;; 3rd line major modes 2nd part
                ((""                                                                     ""              "space"               nil                                                          default "" "")
                 (""                                                                     "Org-Drill"     "org-drill"           (lambda (&rest _) (org-drill))                               dashboard-navigator "" "")
                 (""                                                                     "Org-Roam"      "org-raom-node-find"  (lambda (&rest _) (org-roam-node-find nil "index"))          dashboard-navigator "" "")
                 (""                                                                     "Powershell"    "powershell"          (lambda (&rest _) (powershell))                              dashboard-navigator "" "")
                 (""                                                                     "Shell"         "shell"               (lambda (&rest _) (shell))                                   dashboard-navigator "" "")
                 (""                                                                     "Treemacs"      "treemacs"            (lambda (&rest _) (treemacs))                                dashboard-navigator "" "")
                 )
                ;; 4th line infos
                ((""                                                                     ""              "space"               nil                                                          default "" "")
                 (,(all-the-icons-material   "help_outline" :height 1.1 :v-adjust -0.15) "Help"          "?/h"                 (lambda (&rest _) (describe-mode))                           dashboard-navigator "" "")
                 (,(all-the-icons-material   "help_outline" :height 1.1 :v-adjust -0.15) "My-Help"       "my-help"             (lambda (&rest _) (my-help))                                 dashboard-navigator "" "")
                 (,(all-the-icons-material   "refresh"      :height 1.1 :v-adjust -0.15) "Restart"       "restart-emacs"       (lambda (&rest _) (restart-emacs))                           dashboard-navigator "" "")
                 ))))
    (let ()
      (setq dashboard-navigator-buttons
            ;; list of lines having list of elements
            ;; element: (icon title help action face prefix suffix)
            `(;; 1st line custom views
              (("" ""              "space"               nil                                                          default "" "")
               ("" "Custom Views:" "custom views"        nil                                                          default "" "")
               ("" "ELisp"         "my-view-elisp"       (lambda (&rest _) (my-tab-view-elisp))                       dashboard-navigator "" "")
               ("" "Python"        "my-view-python"      (lambda (&rest _) (my-tab-view-python))                      dashboard-navigator "" "")
               ("" "Shell"         "my-view-shell"       (lambda (&rest _) (my-tab-view-shell))                       dashboard-navigator "" "")
               ("" "Gnuplot"       "my-view-gnuplot"     (lambda (&rest _) (my-tab-view-gnuplot))                     dashboard-navigator "" "")
               ("" "Org-PDF"       "my-view-org-pdf"     (lambda (&rest _) (my-tab-view-org-pdf))                     dashboard-navigator "" "")
               )
              ;; 2nd line major modes 1st part
              (("" ""              "space"               nil                                                          default "" "")
               ("" "Major Modes:"  "major modes"         nil                                                          default "" "")
               ("" "Deft"          "deft"                (lambda (&rest _) (deft))                                    dashboard-navigator "" "")
               ("" "EShell"        "eshell-mode"         (lambda (&rest _) (eshell))                                  dashboard-navigator "" "")
               ("" "Magit"         "magit"               (lambda (&rest _) (magit))                                   dashboard-navigator "" "")
               ("" "Mu4e"          "mu4e"                (lambda (&rest _) (mu4e))                                    dashboard-navigator "" "")
               ("" "Notmuch"       "notmuch"             (lambda (&rest _) (notmuch))                                 dashboard-navigator "" "")
               ("" "Org-Brain"     "org-brain-visualize" (lambda (&rest _) (call-interactively 'org-brain-visualize)) dashboard-navigator "" "")
               )
              ;; 3rd line major modes 2nd part
              (("" ""              "space"               nil                                                          default "" "")
               ("" "Org-Drill"     "org-drill"           (lambda (&rest _) (org-drill))                               dashboard-navigator "" "")
               ("" "Org-Roam"      "org-raom-node-find"  (lambda (&rest _) (org-roam-node-find nil "index"))          dashboard-navigator "" "")
               ("" "Powershell"    "powershell"          (lambda (&rest _) (powershell))                              dashboard-navigator "" "")
               ("" "Shell"         "shell"               (lambda (&rest _) (shell))                                   dashboard-navigator "" "")
               ("" "Treemacs"      "treemacs"            (lambda (&rest _) (treemacs))                                dashboard-navigator "" "")
               )
              ;; 4th line infos
              (("" ""              "space"               nil                                                          default "" "")
               ("" "Help"          "?/h"                 (lambda (&rest _) (describe-mode))                           dashboard-navigator "" "")
               ("" "My-Help"       "my-help"             (lambda (&rest _) (my-help))                                 dashboard-navigator "" "")
               ("" "Restart"       "restart-emacs"       (lambda (&rest _) (restart-emacs))                           dashboard-navigator "" "")
               )))))

  ;; because we use `use-package' include `use-package-statistics' if
  ;; computed
  (setq dashboard-init-info
    (lambda ()
      (let ((package-count 0) (time (emacs-init-time)))
        (when (bound-and-true-p package-alist)
          (setq package-count (length package-activated-list)))
        (when (boundp 'straight--profile-cache)
          (setq package-count (+ (hash-table-count straight--profile-cache) package-count)))
        (when (fboundp 'elpaca--queued)
          (setq package-count (length (elpaca--queued))))
        ;; added case
        (when use-package-compute-statistics
          (setq package-count (+ (hash-table-size use-package-statistics) package-count)))
        (if (zerop package-count)
            (format "Emacs started in %s" time)
          (format "%d packages loaded in %s" package-count time)))))

  ;;
  ;; custom section
  ;;

  ;;; define functions for the section
  ;; `clean-buffer-list'
  (defun my-buffer-name-list (&optional special internal)
    "If SPECIAL non-nil then include special buffers.
If INTERNAL non-nil then include internal buffers."
    (let ((b-list (mapcar (function buffer-name) (buffer-list)))
          new-list head)
      (while b-list
        (setq head (car b-list))
        (when (or internal   ;; check if no space is in the fron
                  (not (string= " " (substring head 0 1))))
          (when (or special  ;; check if no star are in the front and back
                    (and (not (string= "*" (substring head 0 1)))
                         (not (string= "*" (cl-subseq head -1)))))
            (push head new-list)))
        (setq b-list (cdr b-list)))
      (nreverse new-list)))
  (defun my-buffer-name-list-special-only ()
    "List only special buffers *...*."
    (let ((b-list (mapcar (function buffer-name) (buffer-list)))
          new-list head)
      (while b-list
        (setq head (car b-list))
        (when (and (string= "*" (substring head 0 1))
                   (string= "*" (cl-subseq head -1)))
          (push head new-list))
        (setq b-list (cdr b-list)))
      (nreverse new-list)))
  ;;; define section function
  (defun dashboard-insert-custom (list-size)
    "Add the list of LIST-SIZE items from buffers list.

Example `dashboard-insert-recent'.
See also `dashboard-insert-section' for the sequence of elements."
    (dashboard-insert-section
     "Special Buffers:"
     (my-buffer-name-list-special-only)  ;; (my-buffer-name-list t)
     list-size
     'custom
     (dashboard-get-shortcut 'custom)
     `(lambda (&rest _) (switch-to-buffer ,el))
     (abbreviate-file-name el)))
  (add-to-list 'dashboard-item-generators  '(custom . dashboard-insert-custom))

  (dashboard-setup-startup-hook))

;; too slow if all levels are displayed for a medium large file,
;; therefore not all levels and if toggled on and mode default off
(use-package indent-guide
  :delight (indent-guide-mode "Ig")  ;; "\u24BE\uFF47"
  ;;:hook (prog-mode . indent-guide-mode)  ;; problem if used in notmuch
  :hook (python-mode . indent-guide-mode)
  :config
  (set-face-attribute 'indent-guide-face nil :foreground "DarkSlateGray")  ;; foreground #535353
  ;;(setq indent-guide-char ":")
  (setq indent-guide-char "\u2502")
  (setq indent-guide-recursive nil)  ;; NOT RECOMMENDED: To show not only one guide line but all guide lines recursively, set indent-guide-recursive non-nil.
    ;; `nil`: only single level, `t`: all levels
  )

;; problem when using 'character in elisp it inserts the guide characters when inserting text before guide characters
;; (use-package highlight-indent-guides
;;   :delight (highlight-indent-guides-mode "\u24BE\uFF47")
;;   :hook (prog-mode . highlight-indent-guides-mode)
;;   :config
;;   (setq highlight-indent-guides-method 'character)  ;; 'fill 'character 'bitmap
;;   (setq highlight-indent-guides-character ?:)       ;; ?:
;;   (setq highlight-indent-guides-auto-enabled nil)   ;; deactivate auto colors
;;   (set-face-foreground 'highlight-indent-guides-character-face "gray30")
;;   )

(use-package rainbow-mode
  :defer t
  :delight (rainbow-mode "Rb"))  ;; " Rbow" "\u24C7"

(use-package focus
  :defer t
  :custom-face (focus-unfocused ((t :inherit shadow))))

(use-package iscroll
  :defer t
  ;; :hook ((special-mode text-mode) . iscroll-mode)
  )

(use-package virtual-auto-fill
  :defer t
  :delight (virtual-auto-fill-mode "Fv")  ;; "\u24CB\uFF46"
  ;;:hook (help-mode . virtual-auto-fill-mode)
  )

(provide 'gui-settings)
;;; gui-settings.el ends here
