
#+PROPERTY: header-args:emacs-lisp :tangle ~/.config/emacs.mine/init.el :mkdirp yes
#+startup: content
* README:
After the first run that installs things, run the following
#+begin_src emacs-lisp :tangle no
                                          ; code-block not tangled
  (all-the-icons-install-fonts)
  (fira-code-mode-set-font)
#+end_src

* Performance
#+begin_src emacs-lisp
  ;;lsp performance improvement
  (setq gc-cons-threshold-original gc-cons-threshold) 
  (setq gc-cons-threshold (* 1024 1024 100))
  (setq read-process-output-max (* 1024 4024))
#+end_src

* Packaging
Initialize Package sources
#+begin_src emacs-lisp
  (require 'package)

  (setq package-archives '(("melpa" . "https://melpa.org/packages/")
                           ("org" . "https://orgmode.org/elpa/")
                           ("elpa" . "https://elpa.gnu.org/packages/")))
  (package-initialize)
  (unless package-archive-contents
    (package-refresh-contents))

  ;; Initialize use-package on non-Linux platforms
  (unless (package-installed-p 'use-package)
    (package-install 'use-package))
#+end_src

#+RESULTS:

Make sure to download packages if not present
#+begin_src emacs-lisp
  (require 'use-package)
  (setq package-native-compile t)
  (setq use-package-always-ensure t)
#+end_src
straight
#+begin_src emacs-lisp
  (defvar bootstrap-version)
  (let ((bootstrap-file
         (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
        (bootstrap-version 5))
    (unless (file-exists-p bootstrap-file)
      (with-current-buffer
          (url-retrieve-synchronously
           "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
           'silent 'inhibit-cookies)
        (goto-char (point-max))
        (eval-print-last-sexp)))
    (load bootstrap-file nil 'nomessage))

  (straight-use-package 'use-package)
  (setq straight-use-package-by-default t)
#+end_src

remove warning by use-package
#+begin_src emacs-lisp
  (custom-set-variables '(warning-suppress-types '((use-package))))
#+end_src

* Basic Configuration
** Better Defaults
#+begin_src emacs-lisp 
  (setq inhibit-startup-message t)
  (scroll-bar-mode -1)              ; Disable visible scrollbar
  (tool-bar-mode -1)                ; Disable the toolbar
  (tooltip-mode -1)                 ; Disable tooltips
  (set-fringe-mode 10)              ; Give some breathing room

  (menu-bar-mode -1)                ; Disable the menu bar
  (winner-mode 1)                   ; Disable the menu bar
  (setq visible-bell nil)           ; Set up the visible bell
  (column-number-mode)              ; Display Column Number in the modline
  (setq use-dialog-box nil)         ; I don't like to confirm anything with a mouse!
  (setq max-mini-window-height 13)   ; Maximum height for resizing mini-windows (the minibuffer and the echo area). = 1 line

  (defalias 'yes-or-no-p 'y-or-n-p) ; I don't want to type 'yes' everytime!, 'y' is enough
  (setq dired-listing-switches "-al --group-directories-first") ; directories first

                                          ;(setq native-comp-deferred-compilation t); emacs 30+ i guess
  (setq comp-deferred-compilation-deny-list '()) ;; turn off bytecompiler warnings
  (setq native-comp-async-report-warnings-errors nil)

  ;; This is to refresh org buffers when reloading agenda
  ;; When I sync from another device.
  (global-auto-revert-mode 1)
  (setq auto-revert-use-notify 1) ; same thing with set to 1 
  (setq auto-revert-verbose t)


#+end_src
Emacs Backups trashing local dir!
#+begin_src emacs-lisp 
  (use-package no-littering)
  (setq auto-save-file-name-transforms
        `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))
  (setq backup-directory-alist `((".*" . "~/.local/share/emacs-backups")))
  (setq make-backup-files t          ; backup of a file the first time it is saved.
        backup-by-copying t          ; don't clobber symlinks
        version-control t            ; version numbers for backup files
        vc-make-backup-files t       ; version control for git/vcs dirs
        delete-old-versions t        ; delete excess backup files silently
        delete-by-moving-to-trash t
        kept-old-versions 6          ; oldest versions to keep when a new numbered backup is made 
        kept-new-versions 9          ; newest versions to keep when a new numbered backup is made 
        auto-save-default t          ; auto-save every buffer that visits a file
        auto-save-timeout 20         ; number of seconds idle time before auto-save (default: 30)
        auto-save-interval 200       ; number of keystrokes between auto-saves (default: 300)
        create-lockfiles nil         ; don't use lockfiles (default: t)
        )
#+end_src
Better Scrolling
#+begin_src emacs-lisp
  (setq scroll-conservatively 10)
  (setq scroll-margin 3)
  ;; (use-package smooth-scrolling
  ;;    :custom (smooth-scrolling-mode 1))
#+end_src

** Fonts
Setting fonts here as vars to stay sane
#+begin_src emacs-lisp
  (setq my/ui/monofont "JetBrainsMono Nerd Font")
  (setq my/ui/varfont "Noto Serif")
  (setq my/ui/arabicfont "Noto Sans Arabic")
#+end_src

#+begin_src emacs-lisp
  (setq my/ui/font-height 130)
  (set-face-attribute 'default nil :font my/ui/monofont :height my/ui/font-height)
  (set-face-attribute 'fixed-pitch nil :font my/ui/monofont :height my/ui/font-height)
  (set-face-attribute 'variable-pitch nil :font my/ui/varfont :height my/ui/font-height)
  ;; Info has a horrible mono font
  (set-face-attribute 'Info-quoted nil :font my/ui/monofont :height my/ui/font-height)
#+end_src

emacs-client frames don't adhire to the font for some reason, need to
run this hook:
#+begin_src emacs-lisp
  (defun my/ui/font-check ()
    "Do font check, then remove self from `focus-in-hook'; need to run this just once."
    (set-face-attribute 'default nil :font my/ui/monofont :height my/ui/font-height)
    (set-face-attribute 'fixed-pitch nil :font my/ui/monofont :height my/ui/font-height)
    (set-face-attribute 'variable-pitch nil :font my/ui/varfont :height my/ui/font-height)
    ;; Info has a horrible mono font
    (set-face-attribute 'Info-quoted nil :font my/ui/monofont :height my/ui/font-height)
    ;; Arabic
    (when window-system (set-fontset-font "fontset-default" '(#x600 . #x6ff) my/ui/arabicfont))
    (remove-hook 'focus-in-hook #'my/ui/font-check))
  (add-hook 'focus-in-hook #'my/ui/font-check)
#+end_src

Arabic fonts :)
#+begin_src emacs-lisp
  (when window-system (set-fontset-font "fontset-default" '(#x600 . #x6ff) my/ui/arabicfont))
#+end_src

** Theme
Run =M-x= all-the-icons-install-fonts for the first time!
#+begin_src emacs-lisp
  (use-package all-the-icons)
#+end_src

The status line
#+begin_src emacs-lisp
  (use-package doom-modeline
    :ensure t
    :init (doom-modeline-mode 1)
    :config
    (display-battery-mode 1)
    (setq doom-modeline-irc-stylize #'ignore); Fix sever lag https://github.com/seagle0128/doom-modeline/issues/297
    :custom
    ((doom-modeline-height 15) (doom-modeline-icon t)))
#+end_src

buffers with dimmed colors
#+begin_src emacs-lisp
  (use-package solaire-mode
    :init (solaire-global-mode +1))
#+end_src

Actuall Theme:
#+begin_src emacs-lisp
  (use-package doom-themes
    :config
    ;; Global settings (defaults)
    (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
          doom-themes-enable-italic t) ; if nil, italics is universally disabled
    (load-theme 'doom-gruvbox t)
    ;; (load-theme 'doom-one-light t)
    (custom-set-faces
     ;; custom-set-faces was added by Custom.
     ;; If you edit it by hand, you could mess it up, so be careful.
     ;; Your init file should contain only one such instance.
     ;; If there is more than one, they won't work right.
     ;; '(flycheck-warning ((t (:background "#282828" :underline "#fabd2f"))))
     '(org-date ((t (:inherit fixed-pitch))))
     ;; '(ivy-posframe-border ((t (:background "#ffffff")))))

     )

    ;; Enable custom neotree theme (all-the-icons must be installed!)
    (doom-themes-neotree-config)
    ;; or for treemacs users
    (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
    (doom-themes-treemacs-config)
    ;; Corrects (and improves) org-mode's native fontification.
    (doom-themes-org-config))
#+end_src

Transparency!
#+begin_src emacs-lisp
  ;; for the first frame
  (set-frame-parameter nil 'alpha-background 0.9)
  ;; for other frames
  (add-hook 'server-after-make-frame-hook
            (lambda nil  (set-frame-parameter nil 'alpha-background 0.9)))
#+end_src

Center text in the frame, looks nice ;)
#+begin_src emacs-lisp 
  (use-package olivetti
    :diminish
    :hook (text-mode . olivetti-mode)
    :hook (prog-mode . olivetti-mode)
    :hook (magit-mode . olivetti-mode)
    :hook (dired-mode . olivetti-mode)
    :hook (Info-mode . olivetti-mode)
    :config
    (setq-default olivetti-body-width 120))

#+end_src

** Line Numbers
I don't use line numbers anymore, chad.png
    
DEPRECATED Enable Globally
#+begin_src emacs-lisp :tangle no
                                          ; this block has ":tangle no"
  (global-display-line-numbers-mode 0)
#+end_src

DEPRECATED Disable for the following modes
#+begin_src emacs-lisp :tangle no
  (defun disable-line-numbers () "Disables line number" (interactive) (display-line-numbers-mode 0))

  (dolist (mode '(org-mode-hook
                  term-mode-hook
                  treemacs-mode-hook
                  cargo-test-mode-hook
                  shell-mode-hook
                  eshell-mode-hook))
    (add-hook mode #'disable-line-numbers))  

#+end_src
ONLY IN PROG!
#+begin_src emacs-lisp
  ;; (add-hook 'prog-mode-hook 'display-line-numbers-mode)
#+end_src
    
** Undo
Self explanatory
#+begin_src emacs-lisp
  (use-package undo-fu)
#+end_src

** Org roam warning
#+begin_src emacs-lisp
  (setq org-roam-v2-ack t) ; anonying startup message
#+end_src

** Tab Width
*8* Spaces for a single tab is too much
#+begin_src emacs-lisp
  (setq-default tab-width 4)
#+end_src
Spaces > Tabs
#+begin_src emacs-lisp
  (setq-default indent-tabs-mode nil)
#+end_src

#+RESULTS:

** COMMENT Window Management TODO!
#+begin_src emacs-lisp
  (use-package frames-only-mode)
#+end_src

* Auth!
should i really be commiting this? :>
** auth sources
#+begin_src emacs-lisp
  (setq auth-sources '("~/.authinfo.gpg"
                       "secrets:local"; keepassxc db
                       "~/.authinfo"
                       "~/.netrc"))
  (require 'epa-file)
  (epa-file-enable)
#+end_src

* Help
=helpful-key= and =describe-function=
#+begin_src emacs-lisp
  (use-package helpful
    :commands (helpful-callable helpful-variable helpful-command helpful-key)
    :custom
    (counsel-describe-function-function #'helpful-callable)
    (counsel-describe-variable-function #'helpful-variable)
    :bind
    ([remap describe-function] . counsel-describe-function)
    ([remap describe-command] . helpful-command)
    ([remap describe-variable] . counsel-describe-variable)
    ([remap describe-key] . helpful-key))
#+end_src

* Keybinds
Single Esc to Quit, instead of *three*
#+begin_src emacs-lisp
  (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
#+end_src

** Function keys
#+begin_src emacs-lisp
  (global-set-key (kbd "M-<f8>") '(lambda () (interactive) (org-agenda  nil "n")))
  (global-set-key (kbd "<f8>"  ) '(lambda () (interactive) (org-ql-view "Overview: Agenda-like")))
  (global-set-key (kbd "M-<f6>") 'elfeed-dashboard)
#+end_src

** General.el
Eval First and Last at least block!
Edit: honestly I have no clue wtf that meant, or why I wrote it, but I will keep it
*** use-package
#+begin_src emacs-lisp
  (use-package general
    :after evil
    :defer t
    :preface
#+end_src

*** Helper Functions
#+begin_src emacs-lisp
  (defun my/keybind/config ()
    (interactive)
    (counsel-find-file "emacs" "~/.config/"))

  (defun my/keybind/capture-inbox ()
    (interactive)
    (org-capture  nil "gi"))

  (defun my/counsel-insert-file-path ()
    "Insert relative file path using counsel minibuffer"
    (interactive)
    (unless (featurep 'counsel) (require 'counsel))
    (ivy-read "Insert filename: " 'read-file-name-internal
              :matcher #'counsel--find-file-matcher
              :action
              (lambda (x)
                (insert (file-relative-name x)))))
#+end_src

***  leader-keys
**** config head declartion
#+begin_src emacs-lisp
  :config
  (general-create-definer my/leader-keys
    :keymaps 'override
    :states '(normal insert visual emacs)
    :prefix "SPC"
    :global-prefix "C-SPC")

#+end_src

**** Symbols, Spaces, Numbers, u, tabs

#+begin_src emacs-lisp
  (my/leader-keys
    "." '(counsel-find-file :which-key "find file")
    "SPC" '(helm-projectile-find-file-dwim :which-key "projectile find file")
    "/" '(counsel-projectile-rg :which-key "projects")
    "," '(counsel-rg :which-key "rg")
    "u" '(universal-argument :which-key "universal arg")
    ";" '(counsel-M-x :which-key "M-x")
    ":" '(eval-expression :which-key "eval expression")
#+end_src

**** Toggles (t)
#+begin_src emacs-lisp
  "t"  '(:ignore t :which-key "toggles")
#+end_src

**** Help (h)
#+begin_src emacs-lisp 
  "h"  '(:ignore t :which-key "Help")

  "ht" '(counsel-load-theme :which-key "Choose Theme")
  "hk" '(helpful-key :which-key "Describe Key")
  "hf" '(counsel-describe-function :which-key "Describe Function")
  "hv" '(counsel-describe-variable :which-key "Describe Variable")
  "hF" '(counsel-describe-face :which-key "Describe Face")
  "hi" '(info :which-key "info")
  "hm" '(woman :which-key "woman")
#+end_src

**** search (s)
#+begin_src emacs-lisp
  "s"  '(:ignore t :which-key "Search")

  "sb" '(swiper :which-key "swiper")
#+end_src

**** COMMENT Files (f)
Commented for evilem
#+begin_src emacs-lisp 
  "f"  '(:ignore t :which-key "Files")

  "fr" '(counsel-recentf :which-key "Recent Files")
  "fp" '(my/keybind/config :which-key "Config")
  "fd" '(dired :which-key "dired prompt")
  "fD" '(dired-jump :which-key "dired current")
#+end_src

**** Roam and Org, Capture, Inbox(r/C/I)
#+begin_src emacs-lisp
  "r"  '(:ignore t :which-key "Roam+Org")

  "ra"  '(org-agenda :which-key "Agenda")
  "rA"  '(cfw:open-org-calendar :which-key "Calendar")
  "rh" '(helm-org-ql-views :which-key "org-ql views")

  "rD" '(deft :which-key "Deft")
  "rf" '(org-roam-node-find :which-key "Find Note")
  "rl" '(org-roam-buffer-toggle :which-key "Toggle Sidebar")
  "rr" '(org-roam-db-sync :which-key "Roam Sync")
  "ri" '(org-roam-node-insert :which-key "Node  Insert")
  "rI" '(org-id-get-create :which-key "Org Id get/create")
  "rT" '(counsel-org-tag :which-key "Org Id get/create")


  ;; Dailies
  "rd"  '(:ignore t :which-key "Dailies")
  "rdD" '(org-roam-dailies-goto-date :which-key "Go To Date")
  "rdT" '(org-roam-dailies-goto-today :which-key "Go To Today")
  "rdt" '(org-roam-dailies-capture-today :which-key "Capture Today")
  "rdY" '(org-roam-dailies-goto-yesterday :which-key "Go To yesterday")
  "rdy" '(org-roam-dailies-capture-yesterday :which-key "Capture yesterday")
  "rdM" '(org-roam-dailies-goto-tomorrow :which-key "Go To tomorrow")
  "rdm" '(org-roam-dailies-capture-tomorrow :which-key "Capture tomorrow")

  ;; Clocks
  "rc"  '(:ignore t :which-key "Clocks")
  "rci" '(org-clock-in :which-key "Clock In")
  "rcI" '(org-clock-in-last :which-key "Clock In Last")
  "rco" '(org-clock-out :which-key "Clock Out")
  "rcp" '(org-pomodoro :which-key "Pomodoro")
  "rcR" '(org-clock-report :which-key "Clock Report")
  "rcg" '(org-clock-goto :which-key "Goto Clock")

  ;; Anki
  "rn"  '(:ignore t :which-key "AnKi")
  "rnp" '(anki-editor-push-notes :which-key "Clock In")
  "rni" '(anki-editor-insert-notes :which-key "Clock In")


  ;; Schedules and Deadlines
  ;; TODO!
#+end_src
Capture
#+begin_src emacs-lisp
  "C"  '(org-capture :which-key "Org-Capture")
  "I"  '(my/keybind/capture-inbox :which-key "Capture Inbox")
#+end_src

**** Open (o)
#+begin_src emacs-lisp
  "o"  '(:ignore t :which-key "Open")

  "oT" '(vterm :which-key "Vterm in current window")
                                          ; use C-t
                                          ;"ot" '(vterm-toggle :which-key "Vterm in other window")
  "ob" '(bookmark-jump :which-key "Bookmark Jump")
  "oB" '(bookmark-set :which-key "Bookmark set")
  "op" '(list-processes :which-key "List Proccess")

  "om" '(mu4e :which-key "mu4e")
  "ot" '(telega :which-key "Telega")
  "oc" '(circe :which-key "Circe")
  "os" '(easy-hugo :which-key "site")

  "oe" '(elfeed-dashboard :which-key "Elfeed Dashboard")
#+end_src

**** Obsidian (O)
#+begin_src emacs-lisp
  "O"  '(:ignore t :which-key "Obsidian")

  "Oc" '(obsidian-capture         :which-key "Obsidian Capture")
  "Oi" '(obsidian-insert-link     :which-key "Obsidian Insert Link")
  "Ow" '(obsidian-insert-wikilink :which-key "Obsidian Insert Wiki")
  "Oj" '(obsidian-jump            :which-key "Obsidian Jump")
#+end_src

**** Insert (i)
#+begin_src emacs-lisp
  "i"  '(:ignore t :which-key "Insert")
  "ie" '(emoji-insert :which-key "Emoji")
  "if" '(my/counsel-insert-file-path :which-key "Insert Relative path")
  "ik" '(helm-show-kill-ring :which-key "Insert from Kill ring")
#+end_src

**** Buffers (b)
#+begin_src emacs-lisp
  "b"  '(:ignore t :which-key "buffers")

  "bs" '(save-buffer :which-key "Save Buffer")
  "bk" '(kill-current-buffer :which-key "Kill Buffer")
  "bl" '(evil-switch-to-windows-last-buffer :which-key "Last Buffer")
  "bi" '(ibuffer :which-key "Ibuffer")
  "br" '(revert-buffer :which-key "Revert Buffer")
  "bb" '(helm-buffers-list :which-key "Switch to buffer")

  "bc" '(my/circe/helm-buffers :which-key "Circe Helm")
  "bt" '(telega-switch-buffer :which-key "Telega buffers")
#+end_src

**** Windows (w)
#+begin_src emacs-lisp
  "w"  '(:ignore t :which-key "Windows")

  "wj" '(evil-window-down :which-key "Window Down")
  "wk" '(evil-window-up :which-key "Window Up")
  "wl" '(evil-window-right :which-key "Window Left")
  "wh" '(evil-window-left :which-key "Window Down")
  "wJ" '(evil-window-move-very-bottom :which-key "Move Window Down")
  "wK" '(evil-window-move-very-top :which-key "Move Window Up")
  "wL" '(evil-window-move-far-right :which-key "Move Window Left")
  "wH" '(evil-window-move-far-left :which-key "Move Window Down")

  "ws" '(evil-window-split :which-key "Window Split")
  "wv" '(evil-window-vsplit :which-key "Window Vsplit")
  "wd" '(evil-window-delete :which-key "Window delete")
  "wu" '(winner-undo :which-key "Window Undo")
  "wo" '(other-window :which-key "Window Other")
  "wr" '(winner-redo :which-key "Window Redo")
  "wt" '(treemacs :which-key "Treemacs")
  "wT" '(treemacs-select-window :which-key "Treemacs Sel. Window")
#+end_src

**** Code (c)
#+begin_src emacs-lisp
  "c"  '(:ignore t :which-key "code")

  "cE" '(eval-defun :which-key "Eval Function at Point")
  "ce" '(eval-last-sexp :which-key "Eval Function")
  "cb" '(eval-buffer :which-key "Eval Buffer")
  "ca" '(lsp-execute-code-action :which-key "Code Action")
  "cl" '(lsp-avy-lens :which-key "Code Action")
  "ci" '(lsp-ui-imenu :which-key "lsp imenu")
  "cr" '(lsp-rename :which-key "rename")
                                          ;"cs" '(lsp-find-refernces :which-key "find refernces")
  "cd" '(lsp-find-definition :which-key "goto defintion")
  "cD" '(lsp-ui-peek-find-definitions :which-key "goto defintion")
  "cs" '(lsp-ui-peek-find-refernces :which-key "find refernces")
  "cc" '(recompile :which-key "find refernces")
  "cC" '(compile :which-key "find refernces")
#+end_src

**** Git (g)
#+begin_src emacs-lisp
  "g"  '(:ignore t :which-key "Git")
  "gg" '(magit-status :which-key "Magit")
#+end_src

**** Projectile (p)
#+begin_src emacs-lisp
  "p"  '(projectile-command-map t :which-key "Projectile")
#+end_src

**** Quit (q)
#+begin_src emacs-lisp
  "q"  '(:ignore t :which-key "Quit and Stuff")
  "qf" '(delete-frame :which-key "Close Frame")
#+end_src

*** Closing Brackets
#+begin_src emacs-lisp
  ))
#+end_src

** Evil
*** Basic Evil
#+begin_src emacs-lisp
  (use-package evil
    :init
    (setq evil-want-integration t
          evil-want-keybinding nil
          evil-want-C-u-scroll t
          evil-want-C-w-delete t
          evil-want-C-i-jump t
          evil-want-Y-yank-to-eol t
          evil-normal-state-cursor 'box
          evil-emacs-state-cursor  '(box +evil-emacs-cursor-fn); TODO: fix
          evil-insert-state-cursor 'bar
          evil-visual-state-cursor 'hollow
          evil-undo-system 'undo-redo)

    :config
    (evil-mode 1)

    (define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state)
    (define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join)
    (define-key evil-normal-state-map "u" 'undo-fu-only-undo)
    (define-key evil-normal-state-map "\C-r" 'undo-fu-only-redo)
    (define-key evil-normal-state-map "\C-e" 'evil-end-of-line)
    (define-key evil-insert-state-map "\C-a" 'evil-beginning-of-line)
    (define-key evil-insert-state-map "\C-e" 'end-of-line)
    (define-key evil-visual-state-map "\C-e" 'evil-end-of-line)
    (define-key evil-motion-state-map "\C-e" 'evil-end-of-line)
    (define-key evil-normal-state-map "\C-f" 'evil-forward-char)
    (define-key evil-insert-state-map "\C-f" 'evil-forward-char)
    (define-key evil-insert-state-map "\C-f" 'evil-forward-char)
    (define-key evil-normal-state-map "\C-b" 'evil-backward-char)
    (define-key evil-insert-state-map "\C-b" 'evil-backward-char)
    (define-key evil-visual-state-map "\C-b" 'evil-backward-char)

    (define-key evil-insert-state-map "\C-d" 'evil-delete-char)

    (define-key evil-normal-state-map "\C-i" 'evil-jump-forward)

    (define-key evil-normal-state-map "\C-n" 'evil-next-line)
    (define-key evil-insert-state-map "\C-n" 'evil-next-line)
    (define-key evil-visual-state-map "\C-n" 'evil-next-line)
    (define-key evil-normal-state-map "\C-p" 'evil-previous-line)
    (define-key evil-insert-state-map "\C-p" 'evil-previous-line)
    (define-key evil-visual-state-map "\C-p" 'evil-previous-line)
    ;; (define-key evil-normal-state-map "\C-w" 'evil-delete);; in custom
    (define-key evil-insert-state-map "\C-w" 'evil-delete-backward-word)
    (define-key evil-visual-state-map "\C-w" 'evil-delete-backward-word)
    (define-key evil-normal-state-map "\C-y" 'yank)
    (define-key evil-insert-state-map "\C-y" 'yank)
    (define-key evil-visual-state-map "\C-y" 'yank)

                                          ;(define-key evil-normal-state-map "K" 'lsp-ui-doc-glance); moved to lsp-ui
    (define-key evil-visual-state-map "\C-y" 'yank)
    (define-key evil-insert-state-map "\C-k" 'kill-line)
    (define-key evil-normal-state-map "Q" 'call-last-kbd-macro)
    (define-key evil-visual-state-map "Q" 'call-last-kbd-macro)
    ;; (define-key evil-normal-state-map (kbd "TAB") 'evil-undefine)

    ;; Use visual line motions even outside of visual-line-mode buffers
    (evil-global-set-key 'motion "j" 'evil-next-visual-line)
    (evil-global-set-key 'motion "k" 'evil-previous-visual-line)

    (evil-set-initial-state 'messages-buffer-mode 'normal)
    (evil-set-initial-state 'dashboard-mode 'normal))
#+end_src
(Not Working) Emacs State Cursor Color
#+begin_src emacs-lisp
  (defun +evil-default-cursor-fn (interactive)
    (evil-set-cursor-color (get 'cursor 'evil-normal-color)))
  (defun +evil-emacs-cursor-fn () (interactive)
         (evil-set-cursor-color (get 'cursor 'evil-emacs-color)))
#+end_src

*** Evil Collection
#+begin_src emacs-lisp
  (use-package evil-collection
    :after evil
                                          ; :custom
                                          ; (evil-collection-outline-bind-tab-p  t)
    :config
    (evil-collection-init))
#+end_src

*** Evil Escape
#+begin_src emacs-lisp
  ;; ; https://emacs.stackexchange.com/questions/19961/using-jk-to-exit-insert-mode-with-key-chord-or-anything-else
  ;; (defun my-jk ()
  ;;   (interactive)
  ;;   (let* ((initial-key ?j)
  ;;          (final-key ?k)
  ;;          (timeout 0.5)
  ;;          (event (read-event nil nil timeout)))
  ;;     (if event
  ;;         ;; timeout met
  ;;         (if (and (characterp event) (= event final-key))
  ;;             (evil-normal-state)
  ;;           (insert initial-key)
  ;;           (push event unread-command-events))
  ;;       ;; timeout exceeded
  ;;       (insert initial-key))))

  ;; (define-key evil-insert-state-map (kbd "j") 'my-jk)

  (use-package key-chord
    :after evil
    :custom
    (key-chord-two-keys-delay 0.05)
    (key-chord-safety-interval-forward 0.1)
    :config
    (key-chord-mode 1)
    (key-chord-define evil-insert-state-map  "jk" 'evil-normal-state)
    (key-chord-define evil-replace-state-map  "jk" 'evil-normal-state))

  ;; (use-package evil-escape
  ;;   :after evil
  ;;   :init
  ;;   (setq  'evil-escape-excluded-major-modes '(magit-status-mode))
  ;;   (evil-escape-mode)
  ;;   :config
  ;;   (setq evil-escape-key-sequence "jk")
  ;;   (setq evil-escape-delay 0.2)
  ;;   (setq evil-escape-unordered-key-sequence t))

#+end_src

*** Evil args
[[https://github.com/wcsmith/evil-args][wcsmith/evil-args: Motions and text objects for delimited arguments in Evil.]]
#+begin_src emacs-lisp
  (use-package evil-args
    :config
    ;; bind evil-args text objects
    (define-key evil-inner-text-objects-map "a" 'evil-inner-arg)
    (define-key evil-outer-text-objects-map "a" 'evil-outer-arg)

    ;; bind evil-forward/backward-args
    (define-key evil-normal-state-map "L" 'evil-forward-arg)
    (define-key evil-normal-state-map "H" 'evil-backward-arg)
    (define-key evil-motion-state-map "L" 'evil-forward-arg)
    (define-key evil-motion-state-map "H" 'evil-backward-arg)

    ;; bind evil-jump-out-args
    ;; (define-key evil-normal-state-map "K" 'evil-jump-out-args))
    )
#+end_src

*** Evil Easy Motion
[[https://github.com/PythonNut/evil-easymotion][PythonNut/evil-easymotion: A port of vim easymotion to Emacs' evil-mode]]
#+begin_src emacs-lisp
  (use-package evil-easymotion
    :config
    (evilem-default-keybindings "SPC"))

#+end_src

*** evil-org
#+begin_src emacs-lisp
  (use-package evil-org
    :hook (org-mode . evil-org-mode))
#+end_src

*** Evil snipe
[[https://github.com/hlissner/evil-snipe][hlissner/evil-snipe: 2-char searching ala vim-sneak & vim-seek, for evil-mode]]
#+begin_src emacs-lisp
  (use-package evil-snipe
    :config
    (setq evil-snipe-repeat-scope 'whole-visible)
    (evil-snipe-mode +1))
#+end_src

*** Evil numbers
#+begin_src emacs-lisp
  (use-package evil-numbers
    :config
    (evil-define-key '(normal visual) 'global (kbd "C-c +") 'evil-numbers/inc-at-pt)
    (evil-define-key '(normal visual) 'global (kbd "C-c -") 'evil-numbers/dec-at-pt)
    (evil-define-key '(normal visual) 'global (kbd "C-c C-+") 'evil-numbers/inc-at-pt-incremental)
    (evil-define-key '(normal visual) 'global (kbd "C-c C--") 'evil-numbers/dec-at-pt-incremental)
    )
#+end_src

* Completions
** ivy
Better Completions
#+begin_src emacs-lisp
  (use-package ivy
    :defer t
    :diminish
    :bind (("C-s" . swiper); TODO: move to Keybinds
           :map ivy-minibuffer-map
           ("TAB" . ivy-alt-done)
           ("C-l" . ivy-alt-done)
           ("C-j" . ivy-next-line)
           ("C-k" . ivy-previous-line)
           :map ivy-switch-buffer-map
           ("C-k" . ivy-previous-line)
           ("C-l" . ivy-done)
           ("C-d" . ivy-switch-buffer-kill)
           :map ivy-reverse-i-search-map
           ("C-k" . ivy-previous-line)
           ("C-d" . ivy-reverse-i-search-kill))
    :config
    (ivy-mode 1))
#+end_src
Ivy Rich for having =M-x= description and keybinds
#+begin_src emacs-lisp
  (use-package ivy-rich
    :after counsel
    :init (ivy-rich-mode 1))
#+end_src
Ivy floating
#+begin_src emacs-lisp :tangle no
  (use-package ivy-posframe
    :after ivy
    :diminish
    :custom-face
    (ivy-posframe-border ((t (:background "#ffffff"))))
    :config
    (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-top-center))
          ivy-posframe-height-alist '((t . 20))
          ivy-posframe-parameters '((internal-border-width . 10)))
    (setq ivy-posframe-width 120)
    (setq ivy-posframe-parameters
          '((left-fringe . 8)
            (right-fringe . 8)))

    (ivy-posframe-mode +1))

#+end_src

** COMMENT Counsel
#+begin_src emacs-lisp
  (use-package counsel
    :defer t
    :bind (("M-x" . counsel-M-x)
                                          ;("C-x b" . counsel-ibuffer)
           ("C-x C-f" . counsel-find-file)
           :map minibuffer-local-map
           ("C-r" . 'counsel-minibuffer-history)
           ("C-w" . 'evil-delete-backward-word))
    :config (setq ivy-initial-inputs-alist nil)) ;; Don't start searches with '^'
#+end_src

** Which Key (Shows Next keys)
slow loading! defer it
#+begin_src emacs-lisp
  (use-package which-key
    :defer 10
    :diminish which-key-mode
    :config
    (which-key-mode)
    (setq which-key-idle-delay 1
          which-key-max-display-columns 5))
#+end_src

** Company Mode
#+begin_src emacs-lisp
  (use-package company
    :ensure
    :defer 5
    :diminish company-mode
    :custom
    (company-tooltip-minimum-width 40) ;reduce flicker due to changing width
    (global-company-mode t)
    (company-idle-delay 0.1) ;; how long to wait until popup
    (company-minimum-prefix-length 1) ;; The minimum prefix length for idle completion.
    (company-selection-wrap-around t)
    ;; (company-begin-commands nil) ;; uncomment to disable popup
    :bind
    (:map company-active-map
          ;; ("C-n". company-select-next)
          ("C-w". evil-delete-backward-word)
          ("<tab>" . company-complete-common-or-cycle)
          ("RET" . company-complete-selection)
          ;; ("C-p". company-select-previous)
          ("M-<". company-select-first)
          ("M->". company-select-last)))

  ; THIS WAS SLOWING ME!!!!
  ; (use-package company-box
    ; :after company
    ; :hook (company-mode . company-box-mode))
#+end_src

*** lsp + yasnippet
#+begin_src emacs-lisp
  (defun my-backends ()
    (set (make-local-variable 'company-backends)
         '((company-capf ;; I think this must come first?
            :with
            company-yasnippet
            company-files
            company-dabbrev-code))))
#+end_src

** Prescient
better sorting for ivy, company..
#+begin_src emacs-lisp
  (use-package prescient
    :defer t
    :diminish
    :config (prescient-persist-mode 1))

  (use-package ivy-prescient
    :after counsel
    :init (ivy-prescient-mode 1))

  (use-package company-prescient
    :after company
    :config
    (company-prescient-mode 1)
    (prescient-persist-mode)
    )
  ;; (use-package selectrum-prescient)
#+end_src

** Yasnippet
#+begin_src emacs-lisp
  (use-package yasnippet
    :defer 9
    :config
    (yas-global-mode))

  (use-package yasnippet-snippets
    :after yasnippet)

#+end_src

** Helm
#+begin_src emacs-lisp
  (use-package helm
    :defer t
    :config (helm-autoresize-mode 1))
#+end_src

* Org-Mode
** Set directories
#+begin_src emacs-lisp
  (setq org-directory "~/Documents/Emacs/gtd/"
        org-roam-directory "~/Documents/Emacs/roam/"
        ;; org-s-file (car (org-roam-id-find "34f6b040-ea49-421c-ade6-3834a9c86e0f"))
        ;; org-books-file (concat org-roam-directory "book_list.org")
        org-agenda-files (list org-directory ); org-s-file)
        rmh-elfeed-org-files (list "~/Documents/Emacs/private.el/elfeed.org")
        elfeed-dashboard-file "~/Documents/Emacs/private.el/elfeed-dashboard.org"
        org-preview-latex-image-directory  "~/.cache/ltx/ltximg"
        org-my-anki-file (concat org-roam-directory "anki.org")
        org-my-daily-template-file (concat org-roam-directory "templates/daily.orgcaptmpl")
        org-refile-targets '((org-agenda-files . (:level . 1))))

#+end_src

** use-package 
Modes To Start
#+begin_src emacs-lisp
  (defun my/org-mode/org-mode-setup ()
    (interactive)
    (flyspell-mode 1)
    (org-indent-mode)
    (variable-pitch-mode 0)
    (visual-line-mode 1))
#+end_src
use-package
#+begin_src emacs-lisp
  (use-package org
    :defer t
    :hook (org-mode . my/org-mode/org-mode-setup)
    (org-mode . my/org-mode/load-prettify-symbols); symbols
    (org-mode . auto-fill-mode)
    :config
    (require 'org-tempo)
    (require 'org-habit)
    (add-to-list 'org-file-apps '("\\.xlsx\\'" . default))
    (setq geiser-default-implementation  'guile)
    (setq org-ellipsis " ⤵")
    (setq org-agenda-start-with-log-mode t)
    (setq org-highlight-latex-and-related '(latex))
    (setq org-log-done 'time)
    (setq org-log-into-drawer t)
    (dolist (face '((org-document-title . 2.0)
                    (org-level-1 . 1.5)
                    (org-level-2 . 1.0)
                    (org-level-3 . 1.0)
                    (org-level-4 . 1.0)
                    (org-level-5 . 1.0)
                    (org-level-6 . 1.0)
                    (org-level-7 . 1.0)
                    (org-level-8 . 1.0)))
      ;; (set-face-attribute (car face) nil :font my/ui/varfont :weight 'regular :height (cdr face)))
      (set-face-attribute (car face) nil :font my/ui/monofont :weight 'regular :height (cdr face)))
                                          ;)

    (setq org-todo-keyword-faces `(("NOW" (:foreground "white" :background "#444527"))
                                   ("NEXT" (:foreground "bright-white" :background "#444527"))))

    (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.5))
    ;; Ensure that anything that should be fixed-pitch in Org files appears that way
    (set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
    (set-face-attribute 'org-code nil   :inherit '(shadow fixed-pitch))
    (set-face-attribute 'org-table nil   :inherit '(shadow fixed-pitch))
    (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
    (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
    (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
    (set-face-attribute 'org-todo nil :background "#444527" )
    (set-face-attribute 'org-done nil :strike-through t)
    (set-face-attribute 'org-headline-done nil :strike-through t)
    (set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch))
#+end_src

Capture Templates
#+begin_src emacs-lisp
  (use-package doct
    :ensure t
    ;;recommended: defer until calling doct
    :commands (doct))
#+end_src

** Open with external app
#+begin_src emacs-lisp
  ;; Excel with xdg-open
  ;;(add-to-list 'org-file-apps '("\\.xlsx\\'" . default))
  ;; moved to org use package
#+end_src

** Appearance
*** Symbols
#+begin_src emacs-lisp
  (defun my/org-mode/load-prettify-symbols ()
    (interactive)
    (setq prettify-symbols-alist
          (mapcan (lambda (x) (list x (cons (upcase (car x)) (cdr x))))
                  '(("#+begin_src" . ?)
                    ("#+end_src" . ?)
                    ("#+begin_example" . ?)
                    ("#+end_example" . ?)
                    ("#+header:" . ?)
                    ("#+name:" . ?﮸)
                    ("#+title:" . "")
                    ("#+results:" . ?)
                    ("#+call:" . ?)
                    (":properties:" . ?)
                    (":logbook:" . ?))))
    (prettify-symbols-mode 1))
#+end_src

*** COMMENT Visual Fill (center)
I now use olivetti mode, this code block is ignored!
#+begin_src emacs-lisp :tangle no
  (defun my/org-mode/org-mode-visual-fill ()
    (interactive)
    (setq visual-fill-column-width 110
          visual-fill-column-center-text t
          fill-column 90)
    (visual-fill-column-mode 1))
#+end_src
#+begin_src emacs-lisp :tangle no
  (use-package visual-fill-column; center text
    :hook (org-mode . my/org-mode/org-mode-visual-fill))
#+end_src

*** org-bullets
#+begin_src emacs-lisp
  (use-package org-bullets
    :after org
    :hook (org-mode . org-bullets-mode)
    :custom
    (org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
#+end_src

*** Latex
scale inline
#+begin_src emacs-lisp
                                          ;  moved to use -package
                                          ; (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.5))
#+end_src

** Babel
Don't confirm, I know what I am doing!
#+begin_src emacs-lisp
  (setq org-confirm-babel-evaluate nil)
#+end_src

*** Language List
#+begin_src emacs-lisp
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((emacs-lisp . t)
     (python . t)
                                          ;(restclient . t)
     (sql . t)
                                          ;(mermaid . t)
     (octave . t)
     (scheme . t)
     (shell . t)))
#+end_src

*** Structure Templates
Allow fast code insertion
#+begin_src emacs-lisp
  ;; This is needed as of Org 9.2

  (add-to-list 'org-structure-template-alist '("sh" . "src shell"))
  (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
  (add-to-list 'org-structure-template-alist '("re" . "src restclient"))
  (add-to-list 'org-structure-template-alist '("sq" . "src sql"))
  (add-to-list 'org-structure-template-alist '("sql" . "src sql"))
  (add-to-list 'org-structure-template-alist '("oc" . "src octave"))
  (add-to-list 'org-structure-template-alist '("py" . "src python"))
  (add-to-list 'org-structure-template-alist '("scm" . "src scheme"))
#+end_src

#+RESULTS:

*** Mermaid graphs
#+begin_src emacs-lisp :tangle no
                                          ; :tangle no
  (use-package ob-mermaid
    :after org)
#+end_src

** Capture 
*** Templates
#+begin_src emacs-lisp
  (setq org-capture-templates
        (doct `(("Consume: Read/watch" :keys "c"
                 :file ,(concat org-directory "inbox.org")
                 :prepend t
                 :template ("* %{todo-state} %^{Description}"
                            ":PROPERTIES:"
                            ":Created: %U"
                            ":END:"
                            "%?")
                 :children (("Read"   :keys "r"
                             :headline "Read"
                             :todo-state "TODO")
                            ("Watch" :keys "w"
                             :headline "Watch"
                             :todo-state "TODO")))
                ("Ideas" :keys "i"
                 :file ,(concat org-directory "inbox.org")
                 :prepend t
                 :template ("* %{todo-state} %^{Description}"
                            ":PROPERTIES:"
                            ":Created: %U"
                            ":END:"
                            "%?")
                 :children (("Project"   :keys "p"
                             :olp ("Ideas" "Project")
                             :todo-state "")
                            ("Research"   :keys "r"
                             :olp ("Ideas" "Research")
                             :todo-state "")
                            ("Blogs"   :keys "b"
                             :olp ("Ideas" "Blog")
                             :todo-state "")
                            ("Want to Buy"   :keys "w"
                             :olp ("Ideas" "Buy")
                             :todo-state "")
                            ("placeholder" :keys "z"
                             :headline "Watch"
                             :todo-state "TODO")))
                ("GTD" :keys "g"
                 :file ,(concat org-directory "inbox.org")
                 :prepend t
                 :template ("* %{todo-state} %^{Description}"
                            "SCHEDULED: %t"
                            ":PROPERTIES:"
                            ":Created: %U"
                            ":END:"
                            "%?")
                 :children (("Inbox"   :keys "i"
                             :headline "Inbox"
                             :todo-state "")
                            ("placeholder" :keys "w"
                             :headline "Watch"
                             :todo-state "TODO"))))))
#+end_src

*** Utils
launch with =emacsclient -e '(make-orgcapture-frame)'=
From: https://yiufung.net/post/anki-org/
#+begin_src emacs-lisp
  (defun make-orgcapture-frame ()
    "Create a new frame and run org-capture."
    (interactive)
                                          ;(make-frame '((name . "org-capture") (window-system . x))); window-system breaks for some reason :(
    (make-frame '((name . "org-capture")))
    (select-frame-by-name "org-capture")
    (counsel-org-capture)
    (delete-other-windows)) 
#+end_src

** Agenda
*** Customizations
#+begin_src emacs-lisp
  ;;laggy :(
  (setq org-agenda-show-outline-path nil
        org-deadline-warning-days 30)
#+end_src

*** T/ODOs
#+begin_src emacs-lisp
  (setq org-todo-keywords '((sequence "TODO(t!)" "NOW(o)" "NEXT(n)" "|" "DONE(d!)")
                            (sequence "|" "CANCELED(c!)")))
#+end_src

*** start on sunday!
#+begin_src emacs-lisp
  (setq org-agenda-start-on-weekday 0 ;0 is sunday
        org-agenda-weekend-days '(5 6))
#+end_src

*** Start day on 4am
#+begin_src emacs-lisp
  ; It doesn't make sense to reset days at 00:00, since I work late!
  (setq org-extend-today-until 4)
#+end_src

*** Weeks per semester
#+begin_src emacs-lisp
  (defun org-week-to-class-week (week)
    (- week 0))

  (advice-add 'org-days-to-iso-week :filter-return 
              #'org-week-to-class-week)

#+end_src
*** Go EVIL!
#+BEGIN_SRC emacs-lisp
  (eval-after-load 'org-agenda
    '(progn
       (evil-set-initial-state 'org-agenda-mode 'normal)
       (evil-define-key 'normal org-agenda-mode-map
         (kbd "<RET>") 'org-agenda-goto
  ;;;; (kbd "\t") 'org-agenda-goto

         "q" 'org-agenda-quit
         "S" 'org-save-all-org-buffers

  ;;;; Clocking
         "c" nil
         "ci" 'org-agenda-clock-in
         "co" 'org-agenda-clock-out
         "cx" 'org-agenda-clock-cancel
         "cR" 'org-agenda-clockreport-mode

  ;;;; Properties
         "s" 'org-agenda-schedule
         "d" 'org-agenda-deadline
         "p" 'org-agenda-priority
         "+" 'org-agenda-priority-up
         "-" 'org-agenda-priority-down
         "t" 'org-agenda-todo
         "T" 'counsel-org-tag
         ":" 'org-agenda-set-tags
         "e" 'org-agenda-set-effort

  ;;;; Movement
         "j"  'org-agenda-next-line
         "k"  'org-agenda-previous-line
         "f" 'org-agenda-later
         "b" 'org-agenda-earlier
         "J" 'org-agenda-next-date-line
         "K" 'org-agenda-previous-date-line
         "." 'org-agenda-goto-today

  ;;;; View toggles
         "vt" 'org-agenda-toggle-time-grid
         "vw" 'org-agenda-week-view
         "vd" 'org-agenda-day-view
         "vl" 'org-agenda-log-mode
         "vr" 'org-agenda-redo
         "r" 'org-agenda-redo;; often used
         "F" 'org-agenda-follow-mode

  ;;;; Other
         "C" 'org-capture
         "R" 'my/org-agenda/process-inbox-item
         "A" 'org-agenda-archive
         "g/" 'org-agenda-filter-by-tag
         "gr" 'org-ql-view-refresh
         "gh" 'helm-org-ql-views
  ;;;; cool but inactive
         ;; "gj" 'org-agenda-goto-date
         ;; "gJ" 'org-agenda-clock-goto
         "gm" 'org-agenda-bulk-mark
         "go" 'org-agenda-open-link
         ;; "y" 'org-agenda-todo-yesterday
         ;; "n" 'org-agenda-add-note
         ;; ";" 'org-timer-set-timer
         ;; "I" 'helm-org-task-file-headings
         ;; "i" 'org-agenda-clock-in-avy
         ;; "O" 'org-agenda-clock-out-avy
         ;; "u" 'org-agenda-bulk-unmark
         ;; "x" 'org-agenda-exit
         ;; "va" 'org-agenda-archives-mode
         ;;"vc" 'org-agenda-show-clocking-issues
         ;; "o" 'delete-other-windows
         ;; "gh" 'org-agenda-holiday
         ;; "gv" 'org-agenda-view-mode-dispatch
         "n" nil  ; evil-search-next
         ;; "{" 'org-agenda-manipulate-query-add-re
         ;; "}" 'org-agenda-manipulate-query-subtract-re
         ;; "0" 'evil-digit-argument-or-evil-beginning-of-line
         ;; "<" 'org-agenda-filter-by-category
         ;; ">" 'org-agenda-date-prompt
         ;; "H" 'org-agenda-holidays
         ;; "L" 'org-agenda-recenter
         ;; "Z" 'org-agenda-sunrise-sunset
         ;; "T" 'org-agenda-show-tags
         ;; "X" 'org-agenda-clock-cancel
         ;; "[" 'org-agenda-manipulate-query-add
         ;; "g\\" 'org-agenda-filter-by-tag-refine
         ;; "]" 'org-agenda-manipulate-query-subtract
         )))
  ;; TODO check this
#+END_SRC

*** habits: =better-org-habit.el=!
#+begin_src emacs-lisp
  ;; (use-package better-org-habit
    ;; :straight (better-org-habit :type git :host github :repo "vberezhnev/better-org-habit.el"))

  ;; (setq org-habit-graph-column 80   ; prevent overwriting title
  ;;       org-habit-show-habits-only-for-today 't
  ;;       org-habit-show-all-today nil) ; show even if DONE
  ;; (with-eval-after-load 'org-habit
  ;;   (defun org-habit-streak-count ()
  ;;   (goto-char (point-min))
  ;;   (while (not (eobp))
  ;;       ;;on habit line?
  ;;       (when (get-text-property (point) 'org-habit-p)
  ;;       (let ((streak 0)
  ;;               (counter (+ org-habit-graph-column (- org-habit-preceding-days org-habit-following-days)))
  ;;               )
  ;;           (move-to-column counter)
  ;;           ;;until end of line
  ;;           (while (= (char-after (point)) org-habit-completed-glyph)
  ;;                   (setq streak (+ streak 1))
  ;;                   (setq counter (- counter 1))
  ;;                   (backward-char 1))
  ;;           (end-of-line)
  ;;           (insert (number-to-string streak))))
  ;;       (forward-line 1)))

  ;;   (add-hook 'org-agenda-finalize-hook 'org-habit-streak-count))

#+end_src

*** org SUPER agenda
#+begin_src emacs-lisp
      (use-package org-super-agenda
        :after org-agenda
        :config
        (setq org-agenda-span 'day); a week is too much
        (setq org-super-agenda-groups
              '((:log t :order 99); logs at bottom
                (:name "Study"
                       :order 88
                       :tag ("S"))
                (:name "Conferences, Journals, and Papers"
                       :order 90
                       :tag ("conf"))
                (:name "Life"
                       :order 91
                       :tag ("L"))
                (:name "Habits"
                       :order 92
                       :habit t)
                (:name "To Refile"
                       :tag ("INBOX")
                       :order 93)
                (:name "Overdue"
                       :deadline past
                       :scheduled past)
                (:name "Today" ; today is what
                       :time-grid t    ; Items that appear on the time grid
                       :scheduled today)
                (:name "Now" ; today is what
                       :todo "NOW")
                (:name "Deadlines"
                       :deadline t)))

        (org-super-agenda-mode 1)

        :hook (org-agenda-mode . origami-mode)
        (org-agenda-mode . org-super-agenda-mode); need this sadly
        (org-agenda-mode . olivetti-mode)
                                              ;(org-agenda-mode . olivetti-mode)
                                              ;(evil-define-key '(normal visual) 'org-super-agenda-header-map "j" 'org-agenda-next-line)
        :bind (:map org-super-agenda-header-map
                    ([tab] . origami-toggle-node)
                    ;; evil doesn't work on headers, bruh
                    ("j" . org-agenda-next-line)
                    ("k" . org-agenda-previous-line)
                    ("h" . evil-backward-char)
                    ("l" . evil-forward-char)))
#+end_src

*** COMMENT org-ql
#+begin_src emacs-lisp
  (use-package helm-org-ql :after org-ql)
#+end_src

#+begin_src emacs-lisp
                                          ; TODO: tasks not in inbox, and have no schedule/effort/etc
  (use-package org-ql
    :config
    (setq org-ql-views (list
                        (cons "Agenda:Today"
                              (list :buffers-files #'org-agenda-files
                                    :query '(and (not (done))
                                                 (or (deadline auto)
                                                     (scheduled :to today)
                                                     (todo "NOW")
                                                     (ts-active :on today)))
                                    :sort '(priority date todo)
                                    :super-groups 'org-super-agenda-groups
                                    :title "Overview: Today"))
                        (cons "To Refile"
                              (list :buffers-files #'org-agenda-files
                                    :query '(or
                                             (parent (tags "INBOX"))
                                             (done))
                                    :super-groups '((:name "Done" :todo "DONE")
                                                    (:name "Canceled" :todo "CANCELED")
                                                    (:name "Inbox" :anything))
                                    :title "Inbox"))
                        (cons "Plans"
                              (list :buffers-files #'org-agenda-files
                                    :query '(and
                                             (parent (tags "PLAN"))
                                             (not (done)))
                                    :super-groups '((:auto-outline-path))
                                    :sort '(priority  date todo)
                                    :title "Plans"))
                        (cons "Consoom and Create"
                              (list :buffers-files #'org-agenda-files
                                    :query '(parent (tags "READ" "WATCH" "TO_BLOG"))
                                    :super-groups '((:tag "READ")
                                                    (:tag "WATCH")
                                                    (:tag "TO_BLOG"))
                                    :sort '(todo)
                                    :title "Goals"))
                        (cons "Orphans"
                              (list :buffers-files #'org-agenda-files
                                    :query '(and ;(not (todo))
                                             (not (done))
                                             (not (effort))
                                             (not (tags "NOT_ORPHAN" "INBOX"))
                                             (not (scheduled))
                                             (not (deadline))
                                             (parent))))
                        (cons "Quick Picks"
                              (list :buffers-files #'org-agenda-files
                                    :query '(and (not (done))
                                                 (effort <= 10))
                                    :sort '(todo)
                                    :super-groups 'org-super-agenda-groups
                                    :title "Quick Picks")))))

#+end_src

*** COMMENT org-timeblock
#+begin_src emacs-lisp
  (use-package org-timeblock
    :straight (org-timeblock :type git
                             :host github
                             :repo "ichernyshovvv/org-timeblock"))

#+end_src

*** COMMENT org-hyperscheduler
#+begin_src emacs-lisp
  (use-package org-hyperscheduler
    :straight
    ( :repo "dmitrym0/org-hyperscheduler"
      :host github
      :type git
      :files ("*"))
    :custom
    (org-hyperscheduler-readonly-mode nil))
#+end_src

*** Helper functions
Stolen from: [[https://blog.jethro.dev/posts/processing_inbox/][Org-mode Workflow Part 2: Processing the Inbox · Jethro Kuan]]
#+begin_src emacs-lisp
  (defun my/org-agenda/process-inbox-item ()
    "Process a single item in the org-agenda."
    (interactive)
    (org-with-wide-buffer
     (org-agenda-set-tags)
                                          ;(org-agenda-priority)
     (org-agenda-set-effort)
     (org-agenda-refile nil nil t)))

#+end_src

*** Calfw calendar
#+begin_src emacs-lisp
  (use-package calfw :after org)
  (use-package calfw-org
    :after calfw
    :config
                                          ; looks nice
    (setq cfw:fchar-junction ?╬
          cfw:fchar-vertical-line ?║
          cfw:fchar-horizontal-line ?═
          cfw:fchar-left-junction ?╠
          cfw:fchar-right-junction ?╣
          cfw:fchar-top-junction ?╦
          cfw:fchar-top-left-corner ?╔
          cfw:fchar-top-right-corner ?╗)
    (evil-set-initial-state 'cfw:details-mode 'emacs))
#+end_src

** org-pomodoro
#+begin_src emacs-lisp
  (use-package org-pomodoro
    :defer t
    :custom
    (org-pomodoro-length 25)
    (org-pomodoro-keep-killed-pomodoro-time t)
    (org-pomodoro-manual-break t))
#+end_src

** Org analyzer
#+begin_src emacs-lisp
  ;(use-package org-analyzer)
#+end_src

** org-appear
#+begin_quote
 Make invisible parts of Org elements appear visible.
#+end_quote

#+begin_src emacs-lisp
  (use-package org-appear
    :straight (org-appear :type git :host github :repo "awth13/org-appear")
    :hook (org-mode . org-appear-mode)
    :config
    (setq org-appear-autolinks t
          org-hide-emphasis-markers t
          org-appear-delay 0.5))
#+end_src
** org-roam
*** use-package
#+begin_src emacs-lisp
  (use-package org-roam
    :defer t
    :custom
    (org-roam-completion-everywhere t)
    (org-roam-db-gc-threshold most-positive-fixnum) ;; preformance
    
     ;;; Capture Templates
    ;; Dailies
    (org-roam-dailies-capture-templates
     `(("d" "default" entry "* %?" :target
        (file+head "%<%Y-%m-%d>.org" ,(concat "%[" org-my-daily-template-file "]")))))

     ;; Capture Templates
     (org-roam-capture-templates
      '(("d" "default" plain "%?" :target
         (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
         :unnarrowed t)))
     
     ;; (org-roam-capture-ref-templates
     ;;  '(("r" "ref" plain "%?" :if-new
     ;;     (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}")
     ;;     :unnarrowed t)))
     :config
     ;; side window
     ;;(require 'org-roam-protocol)
     (org-roam-db-autosync-mode)
     (add-to-list 'display-buffer-alist
                  '("\\*org-roam\\*"
                    (display-buffer-in-side-window)
                    (side . right)
                    (slot . 0)
                    (window-width . 0.33)
                    (window-parameters . ((no-other-window . t)
                                          (no-delete-other-windows . t))))))
#+end_src

*** org roam server
#+begin_src emacs-lisp
  (use-package websocket
    :after org-roam)

  (use-package simple-httpd
    :after org-roam)

  (use-package org-roam-ui
    :straight (org-roam-ui
               :type git
               :host github
               :repo "org-roam/org-roam-ui"
               :files ("*.el" "out"))
    :after org-roam ;; or :after org
    :hook (org-roam . org-roam-ui-mode)
    :config)

#+end_src

*** Deft
#+begin_src emacs-lisp
  (use-package deft
    :after org
    :bind
    :custom
    (deft-strip-summary-regexp "\\`\\(.+\n\\)+\n")
    (deft-recursive t)
    (deft-use-filter-string-for-filename t)
    (deft-default-extension "org")
    (deft-directory org-roam-directory))
  (setq deft-recursive t)
  (setq deft-strip-summary-regexp ":PROPERTIES:\n\\(.+\n\\)+:END:\n")
  (setq deft-use-filename-as-title 't)
#+end_src

** org-download and clip-link
#+begin_src emacs-lisp
  (use-package org-download
    :after org)
  (use-package org-cliplink
    :after org)
#+end_src

** COMMENT org-book
#+begin_src emacs-lisp
  (use-package org-books
    :after org )
#+end_src

**  COMMENT Anki
Stopped using this, I just use Anki like a normal person
#+begin_src emacs-lisp
  (use-package anki-editor
    :after org
    :bind (:map org-mode-map
                ("<f12>" . anki-editor-cloze-region-auto-incr))
    :init
    (setq-default anki-editor-use-math-jax t)

    :config

    (setq anki-editor-create-decks nil ;; Allow anki-editor to create a new deck if it doesn't exist
          anki-editor-org-tags-as-anki-tags t)

    )
#+end_src

* Development
** General
*** Brackets setup

#+begin_src emacs-lisp
  (use-package rainbow-delimiters
    :hook (prog-mode . rainbow-delimiters-mode)
    (prog-mode . show-paren-mode)
                                          ;(prog-mode . electric-pair-local-mode)
    ) 
#+end_src

#+begin_src emacs-lisp
  ;; (use-package paredit :defer t)
#+end_src

#+begin_src emacs-lisp
  (use-package parinfer-rust-mode         ;
    :hook
    (emacs-lisp-mode . parinfer-rust-mode)
    (scheme-mode . parinfer-rust-mode)
    (clojure-mode . parinfer-rust-mode)
    (racket-mode . parinfer-rust-mode)
                                          ;tabs break parinfer rust mode
    (parinfer-rust-mode . (lambda () (setq indent-tabs-mode nil)));
    :init
    (setq parinfer-rust-auto-download t
                                          ; this variable is only available on my fork
          parinfer-rust-disable-troublesome-modes t))
#+end_src

*** Compilation output
When running =M-x compile= the output is colored!
#+begin_src emacs-lisp
  (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter)
#+end_src

*** Projectile
#+begin_src emacs-lisp
  (use-package projectile
    :defer t
    :diminish projectile-mode
    :config (projectile-mode)
    :custom ((projectile-completion-system 'ivy))
    :init
    ;; NOTE: Set this to the folder where you keep your Git repos!
    (when (file-directory-p "~/code")
      (setq projectile-project-search-path '("~/code")))
    (setq projectile-switch-project-action #'projectile-dired))
#+end_src
Counsel Projectile
#+begin_src emacs-lisp 
  (use-package counsel-projectile
    :defer 9
    :config (counsel-projectile-mode))
#+end_src

Helm Projectile
#+begin_src emacs-lisp 
  (use-package helm-projectile
    :defer t
    :config (helm-projectile-mode))
#+end_src

*** Recentf
#+begin_src emacs-lisp
  (use-package recentf
    :defer 10
    :config (recentf-mode  1)
                                          ;  https://github.com/emacscollective/no-littering#suggested-settings
    (with-eval-after-load 'no-littering
      (add-to-list 'recentf-exclude no-littering-var-directory)
      (add-to-list 'recentf-exclude no-littering-etc-directory)))
#+end_src

*** lsp performance
This is done in Performance section
#+begin_src emacs-lisp :tangle no
  (setq gc-cons-threshold 100000000)           ;; 100 mb
  (setq read-process-output-max (* 1024 4024)) ;; 4mb
#+end_src

*** lsp-mode
#+begin_src emacs-lisp
  (use-package lsp-mode
    :commands (lsp lsp-deferred)
     :hook
     (lsp-mode . lsp-inlay-hints-mode)
    ;; (lsp-mode . my/lsp/lsp-mode-setup)
    :custom
    (lsp-headerline-breadcrumb-segments '(path-up-to-project file))
    (lsp-rust-analyzer-cargo-watch-command "clippy")
    (lsp-eldoc-render-all t)
    (lsp-eldoc-enable-hover nil)
    (lsp-ui-doc-show-with-mouse nil)
    (lsp-keep-workspace-alive nil)
    (lsp-auto-execute-action nil) ; always ask for actions, even if there is only one option!
    (lsp-idle-delay 0.6)
    (lsp-completion-provider :capf) 
    (lsp-prefer-flymake nil)
    ;; in Emacs 31.0!!
    ;; (flymake-show-diagnostics-at-end-of-line 'fancy)
    (lsp-idle-delay 0.6)
    (lsp-rust-analyzer-server-display-inlay-hints t)
    (lsp-rust-analyzer-display-parameter-hints t)
                                          ;(setq lsp-keymap-prefix "C-c l")  ;; Or 'C-l', 's-l'
    :config
    (lsp-enable-which-key-integration t)
    (setq lsp-headerline-breadcrumb-enable nil); anonying tabs
    (setq lsp-log-io nil) ; if set to true can cause a performance hit
    (add-hook 'lsp-mode-hook 'lsp-ui-mode)
    (lsp-headerline-breadcrumb-mode -1)
    (flycheck-mode 1)
    :bind
    (:map lsp-mode-map
          ;; ("<tab>" . company-indent-or-complete-common); commented cuz tabs for yasnippet!
          )
    ) 
#+end_src

Lsp UI
#+begin_src emacs-lisp
  (use-package lsp-ui
    :commands lsp-ui-mode
    :custom
    (lsp-ui-peek-always-show t)
    (lsp-ui-doc-mode t)
    (lsp-ui-sideline-show-hover nil)
    ;; (lsp-ui-doc-enable nil)
    :bind
    (:map lsp-ui-mode-map
          ([remap evil-lookup]           . lsp-ui-doc-glance)
          ([remap xref-find-references]  . lsp-ui-peek-find-references)
          ("C-c z" . lsp-ui-doc-focus-frame)
          :map lsp-ui-doc-frame-mode-map
          ("C-g"   . lsp-ui-doc-unfocus-frame)
          ("C-c z" . lsp-ui-doc-unfocus-frame)
          ))
#+end_src

#+RESULTS:

*** lsp treemacs
#+begin_src emacs-lisp
  ;; (use-package lsp-treemacs
  ;;   :after lsp)
#+end_src

*** Flycheck
#+begin_src emacs-lisp
  (use-package flycheck
    :custom-face (flycheck-warning ((t (:underline (:color "#fabd2f" :style line :position line)))))
    (flycheck-error ((t (:underline (:color "#fb4934" :style line :position line)))))
    (flycheck-info ((t (:underline (:color "#83a598" :style line :position line))))))
#+end_src

*** COMMENT Flymake's Flyover
#+begin_src emacs-lisp
  (use-package flyover
    :straight (flyover :type git :host github :repo "konrad1977/flyover")
    :hook (flycheck-mode . flyover-mode)
    :custom
    ;; Display levels
    (flyover-levels '(error warning info))

    ;; Theme integration
    (flyover-use-theme-colors t)
    (flyover-background-lightness 45)
    (flyover-percent-darker 40)
    (flyover-text-tint 'lighter) ;; or 'darker or nil
    (flyover-text-tint-percent 50)

    ;; Checker settings
    (flyover-checkers '(flycheck flymake))
    (flyover-debug nil)

    ;; Optimization
    (flyover-debounce-interval 0.2)

    ;; Positioning
    (flyover-line-position-offset 1)

    ;; Wrapping
    (flyover-wrap-messages t)
    (flyover-max-line-length 80)

    ;; Icon settings
    (flyover-info-icon "")
    (flyover-warning-icon "⚠")
    (flyover-error-icon "✘")
    (flyover-icon-left-padding 0.9)
    (flyover-icon-right-padding 0.9)

    ;; Virtual line indicators
    (flyover-virtual-line-type 'straight-arrow)
    (flyover-virtual-line-icon "──►")

    ;; Visibility
    (flyover-hide-checker-name t)
    (flyover-show-at-eol t)
    (flyover-hide-when-cursor-is-on-same-line t)
    (flyover-show-virtual-line t)

    :config
    ;; Optional face customization
    (custom-set-faces
     '(flyover-error
       ((t :background "#453246"
           :foreground "#ea8faa"
           :height 0.9
           :weight normal)))
     '(flyover-warning
       ((t :background "#331100"
           :foreground "#DCA561"
           :height 0.9
           :weight normal)))
     '(flyover-info
       ((t :background "#374243"
           :foreground "#a8e3a9"
           :height 0.9
           :weight normal)))))

#+end_src

*** Hide Show
#+begin_src emacs-lisp
  (use-package origami
    :hook (prog-mode . origami-mode))
#+end_src

*** show "TODO"s
#+begin_src emacs-lisp
  (use-package hl-todo
    :hook (prog-mode . hl-todo-mode))
#+end_src

*** COMMENT Formatting
#+begin_src emacs-lisp
  (use-package format-all
    ;; :commands (format-all-mode)
    :config
    (setq my/format-all-formatters '(("Verilog" verible)))
    :hook (prog-mode . format-all-mode)
    (format-all-mode . (lambda () (setq format-all-formatters my/format-all-formatters)))
    (format-all-mode . format-all-ensure-formatter))all 
#+end_src

*** Debug
Use the Debug Adapter Protocol for running tests and debugging
#+begin_src emacs-lisp
  (use-package dap-mode
    :hook
    (lsp-mode . dap-mode)
    (lsp-mode . dap-ui-mode))
#+end_src

*** Highlihght Indenation Mode
#+begin_src emacs-lisp :tangle no
  (use-package highlight-indent-guides
    :hook (prog-mode . highlight-indent-guides-mode)
    :custom (highlight-indent-guides-method 'character)
    (highlight-indent-guides-responsive 'top))

#+end_src


** Git
#+begin_src emacs-lisp
  (setq vc-handled-backends '(Git))
#+end_src

*** Magit
#+begin_src emacs-lisp
  (use-package magit
    :commands (magit)
    :custom
    (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))
#+end_src

Magit TODOs!
#+begin_src emacs-lisp
  (use-package magit-todos
    :after magit
    :config
    (magit-todos-mode 1)

    ;; Generate all keyword variants (@, \, upper/lowercase)
    (setq my/magit-todos/doxygen-keywords
          (apply 'append
                 (mapcar (lambda (kw)
                           (list (concat "@" kw)
                                 (concat "@" (downcase kw))
                                 (concat "\\" kw)
                                 (concat "\\" (downcase kw))))
                         '("TODO" "FIXME" "HACK" "NOTE" "BUG" "XXX" "TEMP" "TESTME" "REVIEW" "KLUDGE"))))

    (setq magit-todos-keywords-list
          (delete-dups (append my/magit-todos/doxygen-keywords magit-todos-keywords-list))))
#+end_src

*** TODO Forge
#+begin_src emacs-lisp
                                          ;(use-package forge)
#+end_src

*** Git gutter
#+begin_src emacs-lisp
  (use-package git-gutter
    :hook (prog-mode . git-gutter-mode)
    :config
    (setq git-gutter:update-interval 2))

  (use-package git-gutter-fringe
    :config
    (define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated))
    (define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated))
    (define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240] nil nil 'bottom)
    :ensure t)

#+end_src

** Treemacs
use-package
#+begin_src emacs-lisp
  (use-package treemacs
    :commands (treemacs)
    :init
    (treemacs-project-follow-mode 1)
    (setq treemacs-follow-after-init t
          treemacs-is-never-other-window t
          treemacs-sorting 'alphabetic-case-insensitive-asc))
#+end_src
fix evil keybinds
#+begin_src emacs-lisp
  (use-package treemacs-evil
                                          ;:when (package-installed-p 'evil-collection)
                                          ;:defer t
    :after treemacs
    :init
    :config
    (general-def evil-treemacs-state-map
      [return] #'treemacs-RET-action
      [tab]    #'treemacs-TAB-action
      "TAB"    #'treemacs-TAB-action
      "o v"    #'treemacs-visit-node-horizontal-split
      "o s"    #'treemacs-visit-node-vertical-split))

#+end_src

Get treemacs-lsp
#+begin_src emacs-lisp
  (use-package lsp-treemacs
    :after (treemacs lsp))
  (use-package treemacs-magit
    :after treemacs magit)
  (use-package treemacs-persp
    :after treemacs
    :config (treemacs-set-scope-type 'Perspectives))
#+end_src

** Language
*** COMMENT Arduino
#+begin_src emacs-lisp
  (use-package arduino-mode
    :config
    (lsp-register-client
     (make-lsp-client
      :new-connection (lsp-stdio-connection '("arduino-language-server" "-clangd" "clangd" "-cli" "arduino-cli" "-cli-config" "/home/lambda/.arduino15/arduino-cli.yaml" "-fqbn" "arduino:avr:uno"))
      :activation-fn (lsp-activate-on "arduino")
      :server-id 'arduino-language-server))
    :defer t)
#+end_src

*** Clojure
#+begin_src emacs-lisp
  (use-package cider
    :defer t
    :config (require 'flycheck-clj-kondo)
    :hook   ;(clojure-mode . zprint-format-on-save-mode)
            (clojure-mode . flycheck-mode)
            (clojure-mode . (lambda ()
                     (add-hook 'before-save-hook 'cider-format-buffer nil t)))

                                          ; (clojure-mode . electric-pair-local-mode)
    :bind   (:map cider-mode-map
                  ([remap lsp-find-definition] . cider-find-var)
                  ([remap eval-defun] . cider-eval-list-at-point)
                  ([remap eval-last-sexp] . cider-eval-last-sexp)))
#+end_src

Auto format
#+begin_src emacs-lisp
  (use-package zprint-format
    :after cider)
#+end_src

#+begin_src emacs-lisp
  (use-package flycheck-clj-kondo
    :after cider)
#+end_src

*** Julia
#+begin_src emacs-lisp
  (use-package julia-mode
    :defer t)

  (use-package lsp-julia
    :hook (julia-mode . lsp)
    :config
    (setq lsp-julia-default-environment "~/.julia/environments/v1.12"))

  (use-package julia-snail
    :ensure t
    :hook (julia-mode . julia-snail-mode))
#+end_src

*** Rust
#+begin_src emacs-lisp
  (use-package rust-mode
    :defer t
    :ensure
    ;; :bind (:map rustic-mode-map
    ;;             ("C-c C-c l" . lsp-ui-flycheck-list)
    ;;             ("C-c C-c s" . lsp-rust-analyzer-status)
    ;;             ("<f5>" . rustic-cargo-test)
    ;;             ("C-<f5>" . rustic-cargo-run))
    :config
    ;; uncomment for less flashiness
    ;; (setq lsp-eldoc-hook nil)
    ;; (setq lsp-enable-symbol-highlighting nil)
    ;; (setq lsp-signature-auto-activate nil)

    ;; comment to disable rustfmt on save
    (setq rust-format-on-save t)
    (setq rust-mode-treesitter-derive t)
    ;; (add-hook 'rustic-mode-hook 'my/dev/rustic-mode-hook)
    (add-hook 'rust-mode-hook 'lsp))
    ;; :custom
    ;; (rustic-rustfmt-config-alist '((edition . "2024"))))

  ;; (defun my/dev/rustic-mode-hook ()
  ;;   ;; so that run C-c C-c C-r works without having to confirm, but don't try to
  ;;   ;; save rust buffers that are not file visiting. Once
  ;;   ;; https://github.com/brotzeit/rustic/issues/253 has been resolved this should
  ;;   ;; no longer be necessary.
  ;;   (when buffer-file-name
  ;;     (setq-local buffer-save-without-query t)))
#+end_src

#+RESULTS:
: t

*** Racket
#+begin_src emacs-lisp
  (use-package racket-mode
    :defer t
    :bind (:map racket-mode-map
                ([remap lsp-find-definition] . racket-send-region)
                ([remap eval-defun]          . racket-send-definition)
                ([remap eval-last-sexp]      . racket-send-last-sexp))
    :config
    ;; fix evil-eol
    ;; Source: https://github.com/greghendershott/racket-mode/issues/489#issuecomment-686903522
    (defun evil-eol-racket-send-last-sexp (command &rest args)
      "In normal-state or motion-state, last sexp ends at point."
      (if (and (not evil-move-beyond-eol) (or (evil-normal-state-p) (evil-motion-state-p)))
          (if (or (eobp) (eolp))
              (apply command args)
            (save-excursion
              (forward-char)
              (apply command args)))
        (apply command args)))
    (unless (and (boundp 'evil-move-beyond-eol) evil-move-beyond-eol)
      (advice-add 'racket-send-last-sexp
                  :around 'evil-eol-racket-send-last-sexp)))

#+end_src

*** emacs-lisp
#+begin_src emacs-lisp
  ;; (add-hook 'emacs-lisp-mode-hook 'company-mode)
  (add-hook 'emacs-lisp-mode-hook 'flycheck-mode)
#+end_src

*** COMMENT V
#+begin_src emacs-lisp
  (use-package v-mode
    :defer t
    :preface
    (defun my/lsp/v ()
      (interactive)
      (lsp)
      (flycheck-mode 1)
      (company-mode 1))
    :init
    (delete '("\\.[ds]?va?h?\\'" . verilog-mode) auto-mode-alist)
    ;; :straight (v-mode
    ;;            :type git
    ;;            :host github
    ;;            :repo "damon-kwok/v-mode"
    ;;            :files ("tokens" "v-mode.el"))
    (setq auto-mode-alist
          (cons '("\\(\\.v\\|\\.vv\\|\\.vsh\\)$" . v-mode) auto-mode-alist))
    :hook (v-mode . my/lsp/v)
    :config
    (flycheck-define-checker v-checker
      "A v syntax checker using the v fmt."
      :command ("v" "fmt" "-verify" (eval (buffer-file-name)))
      :error-patterns
      ((error line-start (file-name) ":" line ":" column ": error: " (message) line-end))
      :modes v-mode)
    (add-to-list 'flycheck-checkers 'v-checker)
    :bind-keymap
    ("M-z" . v-menu)
    ("<f6>" . v-menu)
    ("C-c C-f" . v-format-buffer)
    :mode ("\\.v\\.vsh\\'" . 'v-mode))

#+end_src

*** Haskell
#+begin_src emacs-lisp
  (use-package haskell-mode
    :defer t
    :config (require 'lsp-haskell))
#+end_src

#+begin_src emacs-lisp
  (use-package lsp-haskell
    :preface
    ;; lambda symbol
    (defun my/font/pretty-lambdas-haskell ()
      (font-lock-add-keywords
       nil `((,(concat "\\(" (regexp-quote "\\") "\\)")
              (0 (progn (compose-region (match-beginning 1) (match-end 1)
                                        ,(make-char 'greek-iso8859-7 107))
                        nil))))))
    :hook (haskell-mode . lsp)
                                          ;(haskell-literate-mode-hook lsp)
    (prog-mode . electric-pair-local-mode)

    (haskell-mode . my/font/pretty-lambdas-haskell)
    (haskell-mode . flymake-mode)
    :config
    (haskell-indentation-mode -1)
    (add-hook 'before-save-hook 'lsp-format-buffer)
    :custom (haskell-stylish-on-save t))
#+end_src

*** COMMENT yaml
#+begin_src emacs-lisp
  (use-package yaml-mode
    :hook (yaml-mode . lsp))
#+end_src

*** Web
#+begin_src emacs-lisp
  (use-package typescript-mode
    :defer t

    :hook (typescript-mode . electric-pair-mode)
    :hook (typescript-mode . setup-tide-mode)
    :hook (typescript-mode . prettier-mode)
    :hook (typescript-mode . lsp)
    :config  (add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-mode)))

  (use-package tide
    :defer t
    :preface
    (defun setup-tide-mode ()
      (interactive)
      (tide-setup)
      (flycheck-mode +1)
      (setq flycheck-check-syntax-automatically '(save mode-enabled))
      (eldoc-mode +1)
      (tide-hl-identifier-mode +1)
      ;; company is an optional dependency. You have to
      ;; install it separately via package-install
      ;; `M-x package-install [ret] company`
      (company-mode +1))
    :config

    ;; aligns annotation to the right hand side
    (setq company-tooltip-align-annotations t)

    ;; formats the buffer before saving
    ;; (add-hook 'before-save-hook 'tide-format-before-save)
    (add-hook 'before-save-hook 'prettier-js))
#+end_src

svelte
#+begin_src emacs-lisp
  (use-package svelte-mode
    :hook (svelte-mode . lsp)
    (svelte-mode . (lambda ()
                     (add-hook 'before-save-hook 'lsp-format-buffer nil t))))
#+end_src

prettier
#+begin_src emacs-lisp
  (use-package prettier
    :defer t
    )
#+end_src

lsp hooks setups
#+begin_src emacs-lisp
  (add-hook 'html-mode-hook 'lsp)
  (add-hook 'js-mode-hook 'lsp)
  (add-hook 'js-jsx-mode-hook 'lsp)
#+end_src

*** COMMENT Lua
#+begin_src emacs-lisp
  (use-package lua-mode
    :hook (lua-mode . lsp))
#+end_src

*** Markdown
Better Diff in header sizes
#+begin_src emacs-lisp
  (eval-after-load 'markdown-mode
    '(custom-set-faces
      '(markdown-header-face-1 ((t (:inherit markdown-header-face :height 1.7))))
      '(markdown-header-face-2 ((t (:inherit markdown-header-face :height 1.4))))
      '(markdown-header-face-3 ((t (:inherit markdown-header-face :height 1.3))))
      '(markdown-header-face-4 ((t (:inherit markdown-header-face :height 1.2))))
      '(markdown-header-face-5 ((t (:inherit markdown-header-face :height 1.1))))
      '(markdown-header-face-6 ((t (:inherit markdown-header-face :height 1.0))))
      ))
  (add-hook 'markdown-mode-hook 'auto-fill-mode)
  ;; (add-hook 'markdown-mode-hook 'outline-minor-mode)
#+end_src

*** Markdown (Obsidian)
#+begin_src emacs-lisp
  (use-package obsidian
    :config
    (global-obsidian-mode t)
    (obsidian-backlinks-mode t)
    :custom
    ;; location of obsidian vault
    (obsidian-directory "~/Documents/Obsidian/AmmarSeliaman/AmmarSeliaman/")
    ;; Default location for new notes from `obsidian-capture'
    (obsidian-inbox-directory "Notes")
    ;; Useful if you're going to be using wiki links
    (markdown-enable-wiki-links t)

    ;; These bindings are only suggestions; it's okay to use other bindings
    :bind (:map obsidian-mode-map
                ;; Create note
                ; ("C-c C-n" . obsidian-capture)
                ;; If you prefer you can use `obsidian-insert-wikilink'
                ("C-c C-l" . obsidian-insert-link)
                ;; Open file pointed to by link at point
                ("C-c C-o" . obsidian-follow-link-at-point)
                ;; Open a different note from vault
                ("C-c C-p" . obsidian-jump)
                ;; Follow a backlink for the current file
                ("C-c C-b" . obsidian-backlink-jump)))

#+end_src

*** COMMENT Vue
#+begin_src emacs-lisp
  (use-package vue-mode
    :hook (vue-mode . lsp)
    :hook (vue-mode . prettier-js-mode))
#+end_src

*** Scheme (guile)
#+begin_src emacs-lisp
  (use-package geiser-guile
    :defer t
    :bind (:map scheme-mode-map
                ([remap eval-last-sexp] . geiser-eval-last-sexp)))

                                          ;(use-package geiser-guile)
#+end_src

*** Scala
Scala mode for highlighting, indents and motion commands
#+begin_src emacs-lisp
  (use-package scala-mode
    :hook
    (scala-mode . flycheck-mode)
    (scala-mode . lsp)
    (scala-mode . electric-pair-local-mode)
    (scala-mode . (lambda ()
                    (add-hook 'before-save-hook 'lsp-format-buffer nil t)))
    :interpreter
    ("scala" . scala-mode))
#+end_src

Sbt for sbt commands...
#+begin_src emacs-lisp
  (use-package sbt-mode
    :commands sbt-start sbt-command
    :config
    ;; WORKAROUND: https://github.com/ensime/emacs-sbt-mode/issues/31
    ;; allows using SPACE when in the minibuffer
    (substitute-key-definition
     'minibuffer-complete-word
     'self-insert-command
     minibuffer-local-completion-map)
    ;; sbt-supershell kills sbt-mode:  https://github.com/hvesalai/emacs-sbt-mode/issues/152
    (setq sbt:program-options '("-Dsbt.supershell=false")))
#+end_src

#+begin_src emacs-lisp
  ;; for scala
  (use-package lsp-metals)
#+end_src

*** C and cpp
#+begin_src emacs-lisp
  ;; (use-package ccls
  ;;  :hook ((c-mode c++-mode) . (lambda () (require 'ccls) (lsp)))
  ;;       ((c-mode c++-mode) . (lambda () (add-hook 'before-save-hook 'lsp-format-buffer nil t)))
  ;;       ((c-mode c++-mode) . electric-pair-local-mode)
  ;;       ((c-mode c++-mode) . yas-minor-mode))

  (use-package cc-mode
    :defer t
    :hook ((c++-mode cc-mode c-mode) . lsp)
    ((c++-mode cc-mode c-mode) . lsp)
    ((c++-mode cc-mode c-mode) . electric-pair-local-mode)
    ((c++-mode cc-mode c-mode) . yas-minor-mode)
    ((c++-mode cc-mode c-mode) . (lambda ()
                                   (add-hook 'before-save-hook 'lsp-format-buffer nil t))))
#+end_src

CMake
#+begin_src emacs-lisp
  (use-package cmake-mode)
#+end_src

*** COMMENT Ruby
#+begin_src emacs-lisp
  (use-package ruby-mode
    :hook
    (ruby-mode . lsp)
    (ruby-mode . electric-pair-mode)
    (ruby-mode . (lambda ()
                   (add-hook 'before-save-hook 'lsp-format-buffer nil t))))
#+end_src

*** COMMENT python
#+begin_src emacs-lisp
  (use-package elpy
    :ensure t
    :defer t
    :bind ([remap lsp-find-definition] . elpy-goto-definition)
    :config
    (setq elpy-modules (remove 'elpy-module-highlight-indentation elpy-modules))
    :init
                                          ;(advice-add 'python-mode :before 'elpy-enable)
    (elpy-enable))
  (setq python-interpreter "~/.python/venv/bin/python")
  (setq python-shell-interpreter "~/.python/venv/bin/python")

#+end_src

*** COMMENT LaTeX (old, to be deleted)
AucTex (Archived, =:tangle= set to =no=)
#+begin_src emacs-lisp :tangle no
  ;; latexmk
  (use-package magic-latex-buffer
    :custom (magic-latex-buffer 1)
    :defer t)
  (use-package auctex-latexmk
    :defer t)
  ;; company
  (use-package company-math
    :after company)
  (use-package company-auctex
    :after company)
  (use-package company-reftex
    :after company)

  ;;  use cdlatex
  (use-package cdlatex
    :defer t)

  ;; https://gist.github.com/saevarb/367d3266b3f302ecc896
  ;; https://piotr.is/2010/emacs-as-the-ultimate-latex-editor/

  (use-package latex
    :straight auctex
    :defer t
    :custom
    (cdlatex-simplify-sub-super-scripts nil)
    (reftex-default-bibliography
     '("~/Documents/refs.bib"))
    (bibtex-dialect 'biblatex)
    :mode
    ("\\.tex\\'" . latex-mode)
    ;; also see evil-define-key in :config
    :bind (:map LaTeX-mode-map
                ("TAB" . cdlatex-tab)
                ("'" . cdlatex-math-modify)
                ("C-c C-e" . cdlatex-environment))

    :hook
    (LaTeX-mode . flyspell-mode)
    (LaTeX-mode . flycheck-mode)
    (LaTeX-mode . turn-on-reftex)
    ;(LaTeX-mode . auto-fill-mode)
    (LaTeX-mode . format-all-mode)
    (LaTeX-mode . TeX-source-correlate-mode)
    (LaTeX-mode . try/latex-mode-setup)
    (LaTeX-mode . turn-on-cdlatex)
    (LaTeX-mode . origami-mode)
    ;; (LaTeX-mode . TeX-fold-mode)
    (LaTeX-mode . lsp)
    ;; (LaTeX-mode . olivetti-mode);; already set as a text-mode-hook
    ;; (LaTeX-mode . TeX-PDF-mode) ;; what does it do?
    ;; (LaTeX-mode . company-mode) ;; already enabled globaly
    ;; (LaTeX-mode . xenops-mode)  ;; svgs too lagy :(
    ;; (LaTeX-mode . flycheck-mode);; already enabled with lsp
    ;; (LaTeX-mode . LaTeX-math-mode)
    :config

    ;; pressing "$" while selecting text will cycle between \(\) and \[\] environment
    ;; where does \[\] come from? I have no clue! 
    ;;  I only defined \(\) lol
    (setq TeX-electric-math (quote ("\\(" . "\\)")))
    (evil-define-key 'visual 'LaTeX-mode-map
      "$" 'TeX-insert-dollar
      "'" 'cdlatex-math-modify)

    ;; (setq TeX-auto-save t)
    (setq TeX-parse-self t)
    (setq-default TeX-master nil)
    (setq-default TeX-command-default "LatexMK")
    (setq TeX-save-query nil)

    ;; this is becuase i set $out_dir = '/tmp/tex' in `.latexmkrc`
    ;; and I want to enable forward synctex. don't use it if you don't do like me...
    (setq-default TeX-output-dir "/tmp/tex")

    (setq reftex-plug-into-AUCTeX t)

    ;; ;; pdftools
    ;; ;; https://emacs.stackexchange.com/questions/21755/use-pdfview-as-default-auctex-pdf-viewer#21764
    (setq TeX-view-program-selection '((output-pdf "Zathura"))
          ;; TeX-view-program-list '(("PDF Tools" TeX-pdf-tools-sync-view))
          TeX-source-correlate-start-server t) ;; not sure if last line is neccessary
    ;; (add-to-list 'TeX-view-program-selection '(output-pdf "Zathura"))

    ;; clean intermdiate tex crap
    (add-to-list 'LaTeX-clean-intermediate-suffixes '"-figure[0-9]*\\.\\(pdf\\|md5\\|log\\|dpth\\|dep\\|run\\.xml\\)")
    (add-to-list 'LaTeX-clean-intermediate-suffixes '".auxlock")

                                          ; (eval-after-load 'latex
                                          ;   `(dolist (face '((font-latex-sectioning-0-face . 3.0)    ; \part
                                          ;                   (font-latex-sectioning-1-face . 2.5)    ; \chapter
                                          ;                   (font-latex-sectioning-2-face . 2.0)    ; \section
                                          ;                   (font-latex-sectioning-3-face . 1.5)    ; \subsection
                                          ;                   (font-latex-sectioning-4-face . 1.5)))  ; \subsubsection
                                          ;           (set-face-attribute (car face) nil :font my/ui/varfont :weight 'bold  :height (cdr face))))

    ;; to have the buffer refresh after compilation,
    ;; very important so that PDFView refesh itself after comilation
    ;; (add-hook 'TeX-after-compilation-finished-functions
    ;;           #'TeX-revert-document-buffer)

    ;; latexmk
    (require 'auctex-latexmk)
    (auctex-latexmk-setup) ; look here for stuff
    (setq auctex-latexmk-inherit-TeX-PDF-mode t))
#+end_src



Custom functions (Archived, =:tangle= set to =no=)
#+begin_src emacs-lisp :tangle no

  (defun try/latex-mode-setup ()
    (require 'company-reftex)
    (turn-on-reftex)
    (require 'company-auctex)
    (require 'company-math)
    (setq-local company-backends
                
                (append '((company-reftex-labels company-reftex-citations)
                          (company-math-symbols-unicode company-math-symbols-latex company-latex-commands)
                          (company-auctex-macros company-auctex-symbols company-auctex-environments)
                          company-ispell)
                        company-backends)))

#+end_src

Insert from clip
[[https://hershsingh.net/blog/emacs-latex-screenshot/#:~:text=Clipboard%20to%20TeX,-Finally%2C%20I%20have&text=Once%20I%20have%20captured%20the,file%20img%2F.][Quickly insert hand-drawn figures in a LaTeX document in Emacs]]
#+begin_src emacs-lisp
  (defvar latex/insert-image-format "\\begin{center}\\includegraphics[width=\\linewidth]{%s}\\end{center}")
  (defvar latex/insert-figure-format
    "   \\begin{figure}[h]
  \\centering
  \\includegraphics[width=\\linewidth]{%s}
  \\caption{\\label{fig:TODO} TODO}
  \\end{figure}
  \\FloatBarrier")

  (defun latex/insert-image-from-clipboard-insert-filename ()
    (interactive)
    (let* 
        ;; Ask for a filename
        ((image-name (read-string "image-name: "))
         ;; This is getting uply...
         (image-file-location (concat "\"" (expand-file-name (concat (TeX-master-directory) "img/" image-name ".png" )) "\"")))

      ;; Make the "img" directory if it does not exist
      (make-directory (concat (TeX-master-directory) "img") t)

      ;; Copy the image in clipboard to "img/" directory
      (shell-command (concat "xclip -selection clipboard -t image/png -o > " image-file-location))

      ;; Insert the latex snippet to include the figure
      (insert (concat "img/" image-name ))))
  
  (defun latex/insert-image-from-clipboard ()
    (interactive)
    (let* 
        ;; Ask for a filename
        ((image-name (read-string "image-name: "))
         ;; This is getting uply...
         (image-file-location (concat "\"" (expand-file-name (concat (TeX-master-directory) "img/" image-name ".png" )) "\"")))

      ;; Make the "img" directory if it does not exist
      (make-directory (concat (TeX-master-directory) "img") t)

      ;; Copy the image in clipboard to "img/" directory
      (shell-command (concat "xclip -selection clipboard -t image/png -o > " image-file-location))

      ;; Insert the latex snippet to include the figure
      (insert (format latex/insert-image-format (concat "img/" (file-name-nondirectory image-file-location) )))))

  (defun latex/insert-figure-from-clipboard ()
    (interactive)
    (let* 
        ;; Ask for a filename
        ((image-name (read-string "image-name: "))
         ;; This is getting uply...
         (image-file-location (concat "\"" (expand-file-name (concat (TeX-master-directory) "img/" image-name ".png" )) "\"")))

      ;; Make the "img" directory if it does not exist
      (make-directory (concat (TeX-master-directory) "img") t)

      ;; Copy the image in clipboard to "img/" directory
      (message       (concat "xclip -selection clipboard -t image/png -o > " image-file-location))
      (shell-command (concat "xclip -selection clipboard -t image/png -o > " image-file-location))

      ;; Insert the latex snippet to include the figure
      (insert (format latex/insert-figure-format (concat "img/" (file-name-nondirectory (concat image-name ".png")))))))

#+end_src

Folding
#+begin_src emacs-lisp :tangle no
  (use-package outshine                   ;
    :defer t
    :config
    (setq LaTeX-section-list '(
                               ("part" 0)
                               ("chapter" 1)
                               ("section" 2)
                               ("subsection" 3)
                               ("subsubsection" 4)
                               ("paragraph" 5)
                               ("subparagraph" 6)
                               ("begin" 7)))


    (add-hook 'LaTeX-mode-hook #'(lambda ()
                                   (outshine-mode 1)
                                   (setq outline-level #'LaTeX-outline-level)
                                   (setq outline-regexp (LaTeX-outline-regexp t))
                                   (setq outline-heading-alist
                                         (mapcar (lambda (x)
                                                   (cons (concat "\\" (nth 0 x)) (nth 1 x)))
                                                 LaTeX-section-list)))))



  (general-define-key
   :states '(normal visual)
   :keymaps 'LaTeX-mode-map
   "TAB"  '(outshine-cycle :which-key "outshine-cycle"))


#+end_src

ivy bibtex
#+begin_src emacs-lisp :tangle no
  (use-package ivy-bibtex
    :defer t
    :custom
    (bibtex-completion-bibliography
     '("~/Documents/refs.bib"))
    (bibtex-completion-library-path '("~/papers"))
    (bibtex-completion-cite-prompt-for-optional-arguments nil)
    (bibtex-completion-cite-default-as-initial-input t)
    )
#+end_src

*** LaTeX
See: [[https://karthinks.com/software/latex-input-for-impatient-scholars/][LaTeX Input for Impatient Scholars | Karthinks]]
AucTex
#+begin_src emacs-lisp
  (use-package auctex-latexmk
    :after auctex  ;; Ensure it's loaded after AUCTeX
    :config
    (setq LaTeX-command "LaTeXMk")  ;; Use latexmk as the default LaTeX command
    (setq latex-run-command "LaTeXMk"))


  (use-package auctex
    :mode ("\\.tex\\'" . LaTeX-mode)
    :defer t
    :hook 
    (LaTeX-mode . flyspell-mode)
    (LaTeX-mode . flycheck-mode)
    (LaTeX-mode . company-mode)
    (LaTeX-mode . turn-on-reftex)
    (LaTeX-mode . electric-indent-mode)
    (LaTeX-mode . auto-fill-mode)
                                          ;(LaTeX-mode . format-all-mode)
    (LaTeX-mode . TeX-source-correlate-mode)
    (LaTeX-mode . turn-on-cdlatex)
    :custom
    (reftex-default-bibliography '("~/Documents/refs.bib"))
    (bibtex-dialect 'biblatex)
    (TeX-save-query 'nil)
    (reftex-plug-into-AUCTeX 't)
    :config
    (require 'auctex-latexmk)
    (auctex-latexmk-setup) ; look here for stuff
    (setq auctex-latexmk-inherit-TeX-PDF-mode t)

    (evil-define-key 'visual 'LaTeX-mode-map
      "$" 'TeX-insert-dollar
      "'" 'cdlatex-math-modify)
    
    (setq TeX-view-program-selection '((output-pdf "Zathura")))
    (if (eq system-type 'darwin)      
        (setq TeX-view-program-list   ;; Use Skim, it's awesome
              '(("Skim" "/Applications/Skim.app/Contents/SharedSupport/displayline -g -b %n %o %b"))
              TeX-view-program-selection '((output-pdf "Skim"))))
    
    (setq TeX-source-correlate-method 'synctex
          TeX-source-correlate-start-server t
          TeX-auto-save t
          TeX-parse-self t
          TeX-save-query nil
          TeX-master 'dwim)
    (setq-default TeX-output-dir "/tmp/tex")
    (add-to-list 'LaTeX-clean-intermediate-suffixes
                 '"-figure[0-9]*\\.\\(pdf\\|md5\\|log\\|dpth\\|dep\\|run\\.xml\\)")
    (add-to-list 'LaTeX-clean-intermediate-suffixes '".auxlock")
    :custom-face
    (font-latex-sectioning-0-face ((t (:family my/ui/varfont :weight bold :height 3.0))))
    (font-latex-sectioning-1-face ((t (:family my/ui/varfont :weight bold :height 2.5))))
    (font-latex-sectioning-2-face ((t (:family my/ui/varfont :weight bold :height 2.0))))
    (font-latex-sectioning-3-face ((t (:family my/ui/varfont :weight bold :height 1.5))))
    (font-latex-sectioning-4-face ((t (:family my/ui/varfont :weight bold :height 1.5)))))
#+end_src

Lsp LaTeX
#+begin_src emacs-lisp
  (use-package cdlatex
    :defer t
    :hook ((LaTeX-mode . cdlatex-mode)))

  (use-package lsp-latex
    :hook (;(tex-mode . lsp)
           (LaTeX-mode . lsp)))
#+end_src

*** Lean 
#+begin_src emacs-lisp
(use-package lean4-mode
  :commands lean4-mode
  :straight (lean4-mode :type git :host github
                        :repo "leanprover-community/lean4-mode"
                        :files ("*.el" "data")))
#+end_src

*** LLVM
#+begin_src emacs-lisp
  (use-package llvm-ts-mode
    :mode ("\\.ll\\'" . llvm-ts-mode)
    :config
    (add-to-list
     'treesit-language-source-alist
     '(llvm "https://github.com/benwilliamgraham/tree-sitter-llvm"))
    (treesit-install-language-grammar 'llvm))
#+end_src

*** OpenSCAD
#+begin_src emacs-lisp
  (use-package scad-mode
    :defer t)
  
  (use-package scad-dbus
    :after scad-mode
    :straight (:host github :repo "Lenbok/scad-dbus" :branch "master")
    :bind (:map scad-mode-map ("C-c o" . 'hydra-scad-dbus/body)))
#+end_src

*** COMMENT Ledger
Unused, switched to =hledger=
#+begin_src emacs-lisp
  (use-package ledger-mode
    ;; :mode ("\\.dat\\'" "\\.ledger\\'")
    :mode ("\\.ledger\\'")
    :bind (:map ledger-mode-map
                ("C-x C-s" . my/ledger-save))
    :custom (ledger-clear-whole-transactions t)
    :hook ((ledger-mode . flycheck-mode)
           (ledger-mode . flyspell-mode))
    :config
                                          ;(add-hook 'ledger-mode-hook (lambda () (add-hook 'before-save-hook 'ledger-mode-clean-buffer)))
    )

  (use-package flycheck-ledger :after ledger-mode)
#+end_src
*** hledger
#+begin_src emacs-lisp
  (use-package hledger-mode
    :mode ("\\.journal\\'" "\\.hledger\\'")
                                          ;:commands hledger-enable-reporting
    :preface
    (defun hledger/next-entry ()
      "Move to next entry and pulse."
      (interactive)
      (hledger-next-or-new-entry)
      (hledger-pulse-momentary-current-entry))

    (defface hledger-warning-face
      '((((background dark))
         :background "Red" :foreground "White")
        (((background light))
         :background "Red" :foreground "White")
        (t :inverse-video t))
      "Face for warning"
      :group 'hledger)

    (defun hledger/prev-entry ()
      "Move to last entry and pulse."
      (interactive)
      (hledger-backward-entry)
      (hledger-pulse-momentary-current-entry))

    :bind (("C-c j" . hledger-run-command)
           :map hledger-mode-map
           ("C-c e" . hledger-jentry)
           ("M-p" . hledger/prev-entry)
           ("M-n" . hledger/next-entry))
    :init
    (setq hledger-jfile (expand-file-name "~/Documents/ledger/data_2024.hledger")
          hledger-currency-string "SAR"
                                          ;hledger-email-secrets-file (expand-file-name "secrets.el" emacs-assets-directory)
          )
    ;; Expanded account balances in the overall monthly report are
    ;; mostly noise for me and do not convey any meaningful information.
    (setq hledger-show-expanded-report nil)

    (when (boundp 'my-hledger-service-fetch-url)
      (setq hledger-service-fetch-url
            my-hledger-service-fetch-url))

    :config
    (require 'hledger-input)
    (add-hook 'hledger-view-mode-hook #'hl-line-mode)
                                          ;(add-hook 'hledger-view-mode-hook #'center-text-for-reading)

    (add-hook 'hledger-view-mode-hook
              (lambda ()
                (run-with-timer 1
                                nil
                                (lambda ()
                                  (when (equal hledger-last-run-command
                                               "balancesheet")
                                    ;; highlight frequently changing accounts
                                    (highlight-regexp "^.*\\(savings\\|cash\\).*$")
                                    (highlight-regexp "^.*credit-card.*$"
                                                      'hledger-warning-face))))))

    (add-hook 'hledger-mode-hook
              (lambda ()
                (make-local-variable 'company-backends)
                (add-to-list 'company-backends 'hledger-company))))
#+end_src

#+begin_src emacs-lisp
  (use-package flycheck-hledger
    :after (flycheck hledger-mode)
    :demand t)

#+end_src
*** COMMENT Verilog
#+begin_src emacs-lisp

  (setq verilog-linter "verilator --lint-only")
  (setq verilog-auto-newline nil
        verilog-auto-arg-sort t
        verilog-case-fold nil)
                                          ; (setq verilog-indent-level 1)  
  (add-hook 'verilog-mode-hook 'electric-pair-mode)
  (add-hook 'verilog-mode-hook 'lsp)
  (add-hook 'verilog-mode-hook 'flycheck-mode)
  (add-hook 'verilog-mode-hook (lambda ()
                                 (add-hook 'before-save-hook 'verilog-indent-buffer nil t)))

  (with-eval-after-load 'lsp-mode
    (add-to-list 'lsp-language-id-configuration '(verilog-mode . "verilog"))
    (lsp-register-client
     (make-lsp-client :new-connection (lsp-stdio-connection "verible-verilog-ls")
                      :major-modes '(verilog-mode)
                      :server-id 'verible-ls)))

#+end_src
*** SystemVerilog
#+begin_src emacs-lisp
  (use-package verilog-ext
    :hook ((verilog-mode . verilog-ext-mode)
           (verilog-ext-mode . electric-pair-local-mode)
           (verilog-ext-mode . lsp-mode))
    :init
    ;; Can also be set through `M-x RET customize-group RET verilog-ext':
    ;; Comment out/remove the ones you do not need
    (setq verilog-ext-feature-list
          '(font-lock
            xref
            capf
            hierarchy
            eglot
            lsp
                                          ;lsp-bridge
                                          ;lspce
            flycheck
            beautify
            navigation
            template
            formatter
            compilation
            imenu
            which-func
            hideshow
            typedefs
            time-stamp
            block-end-comments
            ports))
    :config
    (verilog-ext-mode-setup))
#+end_src
*** VHDL
#+begin_src emacs-lisp
  (setq lsp-vhdl-server 'vhdl-ls)
  (add-hook 'vhdl-mode-hook 'vhdl-electric-mode)
  (add-hook 'vhdl-mode-hook 'flycheck-mode)
  (add-hook 'vhdl-mode-hook (lambda ()
                              (add-hook 'before-save-hook 'vhdl-beautify-buffer nil t)))
#+end_src

*** Bash
#+begin_src emacs-lisp
  (use-package flymake-shellcheck
    :commands flymake-shellcheck-load
    :init
    (add-hook 'sh-mode-hook 'flymake-shellcheck-load))

#+end_src

*** Nix(OS)
#+begin_src emacs-lisp
  (use-package nix-mode
    :hook (nix-mode .  (lambda ()
                                          ;(add-hook 'before-save-hook 'nix-mode-format nil t)))); doesn't require nixfmt
                         (add-hook 'before-save-hook 'nix-format-buffer nil t))))

#+end_src

*** Zig
#+begin_src emacs-lisp
  (use-package zig-mode
    :hook 
    (zig-mode . lsp-mode)
    (zig-mode . (lambda () (remove-hook 'before-save-hook 'zig-format-buffer t))))
#+end_src

** Tramp
#+begin_src emacs-lisp
                                          ; moved to Git
                                          ; https://emacs.stackexchange.com/questions/16489/tramp-is-unbearably-slow-osx-ssh
                                          ; (setq vc-handled-backends '(Git))
  (setq tramp-backup-directory-alist backup-directory-alist)
  (setq vc-ignore-dir-regexp
        (format "\\(%s\\)\\|\\(%s\\)"
                vc-ignore-dir-regexp
                tramp-file-name-regexp))
  (setq vc-handled-backends '(Git))
                                          ;https://libredd.it/r/emacs/comments/320cvb/projectile_slows_tramp_mode_to_a_crawl_is_there_a/
  (add-hook 'find-file-hook
            (lambda ()
              (when (file-remote-p default-directory)
                (setq-local projectile-mode-line "Projectile"
                            vc-handled-backends '()))))


#+end_src

* Misc
** Restart Emacs
#+begin_src emacs-lisp
  (use-package restart-emacs)
#+end_src

** Vterm
#+begin_src emacs-lisp
  (use-package vterm
    :commands vterm
    :bind (:map vterm-mode-map
                ("C-t" . vterm-toggle))
    :config
    ;;Toggle vterm
    (evil-define-key '(normal visual insert) 'vterm-mode-map (kbd "C-t") 'vterm-toggle)

    :custom
                                          ; claimed to be faster: https://teddit.net/r/emacs/comments/tpey9g/making_vterm_snappy_by_setting_vtermtimerdelay_to/
    (vterm-timer-delay nil)
    :ensure t)
#+end_src

#+begin_src emacs-lisp
  (use-package vterm-toggle)
#+end_src

** Server
#+begin_src emacs-lisp
  (unless (server-running-p) (server-start))
  (add-hook 'server-after-make-frame-hook '(lambda () (set-cursor-color "#FFFFFF")))
#+end_src

** COMMENT ranger
#+begin_src emacs-lisp
  (use-package ranger
    :defer t
    :config (ranger-override-dired-mode t))
#+end_src

** Ligatures
#+begin_src emacs-lisp

  (let ((ligatures `((?-  . ,(regexp-opt '("-|" "-~" "---" "-<<" "-<" "--" "->" "->>" "-->")))
                     (?/  . ,(regexp-opt '("/**" "/*" "///" "/=" "/==" "/>" "//")))
                     ;; (?*  . ,(regexp-opt '("*>" "***" "*/")))
                     (?*  . ,(regexp-opt '("*>" "*/")))
                     (?<  . ,(regexp-opt '("<-" "<<-" "<=>" "<=" "<|" "<||" "<|||::=" "<|>" "<:" "<>" "<-<"
                                           "<<<" "<==" "<<=" "<=<" "<==>" "<-|" "<<" "<~>" "<=|" "<~~" "<~"
                                           "<$>" "<$" "<+>" "<+" "</>" "</" "<*" "<*>" "<->" "<!--")))
                     (?:  . ,(regexp-opt '(":>" ":<" ":::" "::" ":?" ":?>" ":=")))
                     (?=  . ,(regexp-opt '("=>>" "==>" "=/=" "=!=" "=>" "===" "=:=" "==")))
                     (?!  . ,(regexp-opt '("!==" "!!" "!=")))
                     (?>  . ,(regexp-opt '(">]" ">:" ">>-" ">>=" ">=>" ">>>" ">-" ">=")))
                     (?&  . ,(regexp-opt '("&&&" "&&")))
                     (?|  . ,(regexp-opt '("|||>" "||>" "|>" "|]" "|}" "|=>" "|->" "|=" "||-" "|-" "||=" "||")))
                     (?.  . ,(regexp-opt '(".." ".?" ".=" ".-" "..<" "...")))
                     (?+  . ,(regexp-opt '("+++" "+>" "++")))
                     (?\[ . ,(regexp-opt '("[||]" "[<" "[|")))
                     (?\{ . ,(regexp-opt '("{|")))
                     (?\? . ,(regexp-opt '("??" "?." "?=" "?:")))
                     (?#  . ,(regexp-opt '("####" "###" "#[" "#{" "#=" "#!" "#:" "#_(" "#_" "#?" "#(" "##")))
                     (?\; . ,(regexp-opt '(";;")))
                     (?_  . ,(regexp-opt '("_|_" "__")))
                     (?\\ . ,(regexp-opt '("\\" "\\/")))
                     (?~  . ,(regexp-opt '("~~" "~~>" "~>" "~=" "~-" "~@")))
                     (?$  . ,(regexp-opt '("$>")))
                     (?^  . ,(regexp-opt '("^=")))
                     (?\] . ,(regexp-opt '("]#"))))))
    (dolist (char-regexp ligatures)
      (set-char-table-range composition-function-table (car char-regexp)
                            `([,(cdr char-regexp) 0 font-shape-gstring]))))
#+end_src

** Key freq
#+begin_src emacs-lisp
  (use-package keyfreq
    :defer 10
    :custom
    (keyfreq-mode 1)
    (keyfreq-autosave-mode 1))
#+end_src

** Polybar/Waybar
*** org clock
#+begin_src emacs-lisp
  (defun my/polybar/org-clock ()
    "Gets polybar formatted message"
    (let ((message nil)
          (icon nil)
          (icon-color nil))
      (if (org-clock-is-active)
          (setq message (substring-no-properties (org-clock-get-clock-string))
                icon ""; there is an icon here, in case it isn't rendered...
                icon-color "#BA68C8")
        (setq message ""
              icon ""; "";; I want it to be empty
              icon-color "#FDD835"))
      (concat "%{F" icon-color "}" icon  "%{F-}" message)))

#+end_src

#+begin_src emacs-lisp
    
  ;; From Qwen3-Max
  (defun my/waybar/org-clock-get-current-heading ()
    "Return the heading text of the currently clocked item, or nil if none."
    (when (org-clock-is-active)
      (with-current-buffer (marker-buffer org-clock-marker)
        (save-excursion
          (goto-char org-clock-marker)
          (org-get-heading t t t t)))))  ; args: no-tags, no-todo, no-priority, no-comment

  ;; From Qwen3-Max
  (defun my/waybar/org-clock-current-session-string-with-heading ()
    "Return string like '[1:23] (Heading)' for current clocking session."
    (when (org-clock-is-active)
      (let* ((elapsed-minutes (/ (- (float-time) (float-time org-clock-start-time)) 60.0))
             (duration (org-duration-from-minutes elapsed-minutes))
             (heading (my/waybar/org-clock-get-current-heading)))
        (format "[%s] (%s) " duration (or heading "???")))))

    (defun my/waybar/org-clock ()
      "Gets waybar formatted message"
      (let ((message nil)
            (icon nil)
            (enabled t)
            (icon-color nil))
        (if (org-clock-is-active)
            (setq ; message (substring-no-properties (org-clock-get-clock-string))
                  message (my/waybar/org-clock-current-session-string-with-heading)
                  icon ""; there is an icon here, in case it isn't rendered...
                  enabled t
                  icon-color "#BA68C8")
          (setq message ""
                icon ""; "";; I want it to be empty
                enabled nil
                icon-color "#FDD835"))
        (json-encode
         `((text . ,message)
           (icon . ,icon)
           ,@(when enabled '((class . "enabled")))))))
#+end_src

** Gemini
#+begin_src emacs-lisp
  (use-package elpher
    :defer t
    :hook (elpher-mode . olivetti-mode) )
#+end_src

** Easy hugo
#+begin_src emacs-lisp
  (use-package easy-hugo
    :init
    (easy-hugo-enable-menu)
    (setq easy-hugo-basedir "~/code/sites/ammar.engineer/")
    (setq easy-hugo-postdir "content/posts")
    (setq easy-hugo-url "https://ammar.engineer")
    ;; (setq easy-hugo-sshdomain "blogdomain")
    ;; (setq easy-hugo-root "")
    (setq easy-hugo-previewtime "300"))
                                          ;:bind
                                          ;("C-c C-e" . easy-hugo))
#+end_src

* Elfeed org
=;; (setq rmh-elfeed-org-files (list "~/Documents/private.el/elfeed.org"))=
** Elfeed-org
#+begin_src emacs-lisp
  (use-package elfeed-org
    :after elfeed
    :config (elfeed-org))

#+end_src

** Elfeed Dashboard
#+begin_src emacs-lisp
  (use-package elfeed-dashboard
    :commands elfeed-dashboard
    :config
    ;; (setq elfeed-dashboard-file "~/Documents/private.el/elfeed-dashboard.org")
    ;; update feed counts on elfeed-quit
    (advice-add 'elfeed-search-quit-window :after #'elfeed-dashboard-update-links)
    (evil-set-initial-state 'elfeed-dashboard-mode 'emacs)
    :hook (elfeed-dashboard-mode . (lambda () (variable-pitch-mode -1))))

#+end_src

** Helper Functions
From: https://old.reddit.com/r/emacs/comments/hbdlv8/elfeed_mpv_youtube/fv9yhb2/
#+begin_src emacs-lisp
  (defun my/elfeed/visit-entry-dwim (&optional arg)
    (interactive "P")
    (if arg
        (elfeed-search-browse-url)
      (-let [entry (if (eq major-mode 'elfeed-show-mode) elfeed-show-entry (elfeed-search-selected :single))]
        (if (s-matches? (rx "https://www.youtube.com/watch" (1+ any))
                        (elfeed-entry-link entry))
            (let* ((quality (completing-read "Max height resolution (0 for unlimited): " '("0" "480" "720" "1080")))
                   (format (if (= 0 (string-to-number quality)) "" (format "--ytdl-format=[height<=?%s]" quality))))
              (message "Opening %s with height ≤ %s with mpv..."
                       (elfeed-entry-link entry) quality)
              (elfeed-untag entry 'unread)
              (start-process "elfeed-mpv" nil "mpv" format (elfeed-entry-link entry))
              (elfeed-search-update :force))
          (if (eq major-mode 'elfeed-search-mode)
              (elfeed-search-browse-url)
            (elfeed-show-visit))))))
#+end_src

I wrote that, neat isn't it? :P
#+begin_src emacs-lisp
  (defun my/elfeed/toggle-search-tag (tag)
    (interactive)
                                          ;example: tag = "unread"
    (elfeed-search-set-filter
                                          ;s-contains matches agains "+unread"; i.e (concat "+" tag) => "+unread"
     (if (s-contains? (concat "+" tag) elfeed-search-filter)
                                          ;regex will be " ?\\+unread"
         (s-replace-regexp (concat " ?\\+" tag) "" elfeed-search-filter)
                                          ;concat will be " +unread"
       (concat elfeed-search-filter (concat " +" tag)))))

  (defun my/elfeed/toggle-search-unread () (interactive) (my/elfeed/toggle-search-tag  "unread" ))
  (defun my/elfeed/toggle-search-to_read () (interactive) (my/elfeed/toggle-search-tag "to_read"))
#+end_src

** Visual, binds, directory
#+begin_src emacs-lisp
  (use-package elfeed
    :defer t
    :config 
    ;; (defun my/elfeed/visual ()
    ;; (interactive)
    ;;     (set-face-attribute 'variable-pitch (selected-frame) :font (font-spec :family my/ui/varfont :size 13))
    ;;   (setq visual-fill-column-width 110
    ;;         visual-fill-column-center-text t
    ;;         fill-column 90)
    ;;   (visual-fill-column-mode 1)
    ;;   (visual-line-mode 1))

    (elfeed-org)
    (evil-define-key 'normal elfeed-search-mode-map
      "O" 'my/elfeed/visit-entry-dwim
                                          ;"tr" 'my/elfeed/toggle-read
      "tr" 'my/elfeed/toggle-search-unread
      "tt" 'my/elfeed/toggle-search-to_read)
    :custom
    (elfeed-db-directory  "~/.local/share/elfeed")
    :hook ;(elfeed-show-mode  . my/elfeed/visual)
    (elfeed-show-mode  . olivetti-mode))

#+end_src

* IRC
** COMMENT unsused 'erc'
#+begin_src emacs-lisp
  (use-package erc
    :defer t
    :custom
    (erc-autojoin-timing 'ident)
    (erc-fill-function 'erc-fill-static)
    (erc-fill-static-center 25)
    (erc-hide-list '("JOIN" "PART" "QUIT"))
    (erc-lurker-hide-list '("JOIN" "PART" "QUIT"))
    (erc-lurker-threshold-time 43200)
    (erc-prompt-for-nickserv-password nil)
    (erc-server-reconnect-attempts 5)
    (erc-server-reconnect-timeout 3)
    (erc-track-exclude-types '("JOIN" "MODE" "NICK" "PART" "QUIT"
                               "324" "329" "332" "333" "353" "477"))
    :config
    ;; (add-to-list 'erc-modules 'notifications)
    (add-to-list 'erc-modules 'spelling)
    (erc-services-mode 1)
    (erc-update-modules))

  (use-package erc-hl-nicks
    :after erc)

  (use-package erc-image
    :after erc)
#+end_src

#+begin_src emacs-lisp :tangle no
  (use-package znc
    :defer t
    :config
    (setq znc-servers
          `(("flinner.my.to" 6697 t ((main ,my/secret/znc/flinner.my.to/username
                                           ,my/secret/znc/flinner.my.to/secret))))))
  (defun my/znc-all ()
    "Connect to all ZNC networks. Accept incoming self signed certificates."
    (interactive)
    (let ((tls-checktrust nil) 
          (gnutls-verify-error nil)) 
      (znc-all))) 
#+end_src

** circe
*** Secrets :^)
#+begin_src emacs-lisp :tangle no
  ;; Doesn't tangle!
  ;; loaded in use-package (block below)
  (load "~/Nextcloud/Documents/Passwords/circe-networks.el")

                                          ; example content
  (add-to-list 'circe-networks `("chat.name/username" :host "irc.example.com" :port 69
                                 :tls t
                                 :nick "nicky"
                                 :pass ,(secrets-get-secret "local" "hehe :^)")
                                 :user "username")) 
#+end_src

*** Helper Functions!
#+begin_src emacs-lisp
  (defun my/circe/clear ()
    "Clear the buffer"
    (interactive)
    (circe-command-CLEAR))

  (defun my/circe/build-helm-sources (server-buf)
    "Builds helm candidates for a single server"
    (helm-build-sync-source (buffer-name server-buf)
      :candidates
      (cons (cons (buffer-name server-buf) server-buf)
            (cl-loop for buf in (with-current-buffer server-buf (circe-server-chat-buffers))
                     collect (cons
                              (let ((buf-name (buffer-name buf)))
                                (concat buf-name
                                          ; add " ***" if buffer has new messagse
                                        (if (member buf-name tracking-buffers) " ***" "")))
                              buf)))
      :action (list (cons "Switch to circe" #'switch-to-buffer)
                    (cons "Kill buffer" #'kill-buffer))))

  (defun my/circe/helm-buffers ()
    "Switch between circe buffers using helm"
    (interactive)
    (helm :sources
          (cl-loop for server-buf in (circe-server-buffers)
                   collect (my/circe/build-helm-sources server-buf))
          :buffer "*helm circe*"))

#+end_src

*** Setup
#+begin_src emacs-lisp
  (use-package circe
    :defer t
    :preface
    :config
    (enable-lui-track)
                                          ;(add-to-list 'circe-networks `())
    ;; adding to list happens here!
    (load "~/Documents/Passwords/circe-networks.el")
    (setq circe-color-nicks-min-constrast-ratio 4.5
          circe-color-nicks-everywhere t)
    :hook (circe-channel-mode . enable-circe-color-nicks)
    (circe-channel-mode . (lambda () (smooth-scrolling-mode -1)))
    :custom
    (circe-format-say "{nick:-16s} {body}")
    ;; :bind(("C-l" . my/circe/clear))
    :bind (:map circe-mode-map
                ([remap counsel-projectile-find-file] . my/circe/helm-buffers))
    )

  (use-package circe-notifications)
#+end_src
    
#+begin_src emacs-lisp
  (setq
   lui-time-stamp-position 'right-margin
   lui-flyspell-p t
   lui-fill-type nil
                                          ;Display your own nickname instead of >>> in the channel buffers when you're talking.
   circe-format-self-say "{nick:-15s} {body}"
   )

  (add-hook 'lui-mode-hook 'my-lui-setup)
  (defun my-lui-setup ()
    (setf (cdr (assoc 'continuation fringe-indicator-alist)) nil)
    (olivetti-mode 1)
    (setq
     fringes-outside-margins t
     right-margin-width 0
     word-wrap t
     wrap-prefix "    "))
#+end_src

*** znc stuff
#+begin_src emacs-lisp
  (defun circe-command-ZNC (what)
    "Send a message to ZNC incorporated by user '*status'."
    (circe-command-MSG "*status" what))

#+end_src

* Email (mu4e)
** Package
#+begin_src emacs-lisp

  (use-package mu4e                       ;
    ;; this line is for nixos
    ;; until here
    :ensure-system-package mu
    :init
    (defun mu4e--main-action-str (str &optional func-or-shortcut))
    (defun evil-collection-mu4e-update-main-view@override())
    (advice-add 'evil-collection-mu4e-update-main-view :override #'evil-collection-mu4e-update-main-view@override)
    :commands (mu4e)
    :bind   (:map mu4e-main-mode-map
                  ([remap revert-buffer] . mu4e-update-index))
    :custom
    (mu4e-change-filenames-when-moving t)
    (mu4e-html2text-command "iconv -c -t utf-8 | pandoc -f html -t plain")
    (mu4e-attachment-dir "~/Downloads")
    (mu4e-compose-signature-auto-include t)
    (mu4e-get-mail-command "mbsync -a")

    (mu4e-update-interval 300)
    (mu4e-use-fancy-chars t)
    (mu4e-view-show-addresses t)
    (mu4e-view-show-images t)
    :hook
    (mu4e-view-mode . visual-line-mode) 
    (mu4e-view-mode . olivetti-mode) 
    (mu4e-main-mode . olivetti-mode)
    (mu4e-compose-mode . flyspell-mode)
    (mu4e-context-changed . mu4e-update-index))

#+end_src

** Contexts
#+begin_src emacs-lisp
  ;; assumed Maildir layout
  ;; ~/Maildir/Account0/{Inbox,Sent,Trash}
  ;; ~/Maildir/Account1/{Inbox,Sent,Trash}
  ;; where Account0 is context name
  (with-eval-after-load 'mu4e
    (defun my-make-mu4e-context (context-name full-name mail-address signature)
      "Return a mu4e context named CONTEXT-NAME with :match-func matching
      folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
      `user-full-name' and `mu4e-compose-signature' is set to MAIL-ADDRESS
      FULL-NAME and SIGNATURE respectively.
      Special folders are set to context specific folders."
      (let ((dir-name (concat "/" context-name))
            (context-filter (concat " maildir:/" context-name "/")))
        (make-mu4e-context
         :name context-name
         ;; we match based on the maildir of the message
         ;; this matches maildir /Arkham and its sub-directories
         :match-func
         `(lambda (msg)
            (when msg
              (string-match-p
               ,(concat "^" dir-name)
               (mu4e-message-field msg :maildir))))
         :vars
         `(
           (mu4e-bookmarks .
                           ,`(
                                          ;(:name "All Unread messages"  :query ,"flag:unread AND NOT flag:trashed AND NOT flag:list" :key ?a)
                              (:name "All Unread messages"  :query ,"flag:unread AND NOT flag:trashed" :key ?a)
                              (:name "Unread messages"  :query ,(concat "flag:unread AND NOT flag:trashed"  context-filter) :key ?u)
                              (:name "Inbox"            :query ,(concat "maildir:/Inbox/"  context-filter) :key ?i)
                              (:name "Today's messages"     :query ,(concat "date:today..now" context-filter)                   :key ?t)
                              (:name "Last 7 days"          :query ,(concat "date:7d..now" context-filter) :hide-unread t       :key ?w)
                              (:name "Messages with attachments" :query ,(concat "mime:application/*" context-filter)           :key ?p)
                              (:name "Lists"     :query ,(concat "flag:list" context-filter)                   :key ?b)
                              )
                           )
           (mu4e-maildir-shortcuts . ,`(
                                        (:maildir ,(concat dir-name "/Inbox") :key ?i)
                                        (:maildir ,(concat dir-name "/Sent") :key ?s)
                                        (:maildir ,(concat dir-name "/Archive") :key ?a)
                                        (:maildir ,(concat dir-name "/Drafts") :key ?d)
                                        (:maildir ,(concat dir-name "/Junk") :key ?j)
                                        (:maildir ,(concat dir-name "/Trash") :key ?t)
                                        ))

           (mu4e-sent-messages-behavior . delete)
           (user-mail-address    .   ,mail-address)
           ;; (mu4e-maildir         .   ,(concat "~/.mail" dir-name))
           (user-full-name       .   ,full-name)
           (mu4e-sent-folder     .   ,(concat dir-name "/Sent"))
           (mu4e-drafts-folder   .   ,(concat dir-name "/Drafts"))
           (mu4e-trash-folder    .   ,(concat dir-name "/Trash"))
           (mu4e-refile-folder   .   ,(concat dir-name "/Archive"))
           (mu4e-compose-signature . ,signature))))))
  ;;Fixing duplicate UID errors when using mbsync and mu4e
#+end_src


** Email List here!
#+begin_src emacs-lisp :tangle no
  ;; This is a sample, it doesn't get included in init.el
  ;; I put mine at location specified in the  next code block
  ;; any number of email can be used ofc
  (with-eval-after-load 'mu4e
    (setq mu4e-contexts `(
                          ,(my-make-mu4e-context
                            "maildir-context" "Full Name"
                            "Email Address" "Signature")
                          ,(my-make-mu4e-context
                            "maildir-context2" "Full Name2"
                            "Email Address2" "Signature2")
                          )))
#+end_src

or don't include in git source :)
#+begin_src emacs-lisp
  (with-eval-after-load 'mu4e
    (load "~/Documents/Passwords/mu4e-context.el"))
#+end_src

** Other fixes

see: [[https://github.com/djcb/mu/issues/1136][djcb/mu#1136 Shouldn't set flag T after moving to trash]]. Deleting
should only move to trash, not delete entirely from the server

#+begin_src emacs-lisp

  (with-eval-after-load 'mu4e
    (setf (alist-get 'trash mu4e-marks)
          (list :char '("d" . "▼")
                :prompt "dtrash"
                :dyn-target (lambda (target msg)
                              (mu4e-get-trash-folder msg))
                :action (lambda (docid msg target)
                          ;; Here's the main difference to the regular trash mark,
                          ;; no +T before -N so the message is not marked as
                          ;; IMAP-deleted:
                          (mu4e--server-move docid (mu4e--mark-check-target target) "-N")))))

#+end_src

#+begin_src emacs-lisp
  (setq mu4e-completing-read-function 'completing-read);; Use Helm
  (setq message-kill-buffer-on-exit t) ;; Why would I want to leave my message open after I've sent it?
#+end_src

Breaking change betweeen =mu4e-alert= and =mu= :(

(I don't use =mu4e-alert= anymore, but will keep this cuz y not?)
#+begin_src emacs-lisp
  (defvaralias 'mu4e~context-current  'mu4e--context-current)
#+end_src

I prefer text/plain, over everything >:)
#+begin_src emacs-lisp
  (with-eval-after-load "mm-decode"
    (add-to-list 'mm-discouraged-alternatives "text/richtext")
    (add-to-list 'mm-discouraged-alternatives "text/html"))
#+end_src


[[https://github.com/djcb/mu/issues/2665#issuecomment-2016826822][djcb/mu#2665 {mu4e rfe} Switch between "Reply" and "Wide Reply"]]

Supersede rather than reply to my own emails.
Only ask whether to reply to all if there are more than one recipients
#+begin_src emacs-lisp

  (with-eval-after-load 'mu4e
    (defun mu4e-supersede-or-compose-reply-ask-wide ()
      "Supersede own messages or ask whether to reply-to-all."
      (interactive)
      (if (mu4e-message-contact-field-matches-me (mu4e-message-at-point) :from)
          (mu4e-compose-supersede)
        (let ((tos (length (mu4e-message-field-at-point :to)))
              (ccs (length (mu4e-message-field-at-point :cc))))
          (mu4e-compose-reply
           (and (> (+ tos ccs) 1)
                (yes-or-no-p "Reply to all?")))))
      (evil-define-key 'normal mu4e-headers-mode-map "R" 'mu4e-supersede-or-compose-reply-ask-wide)
      (evil-define-key 'normal mu4e-view-mode-map    "R" 'mu4e-supersede-or-compose-reply-ask-wide)))
#+end_src


** Send email (msmtp)
#+begin_src emacs-lisp
  (setq sendmail-program (executable-find "msmtp")  ;"/usr/bin/msmtp"
        message-sendmail-f-is-evil t
        message-sendmail-extra-arguments '("--read-envelope-from")
        send-mail-function 'smtpmail-send-it
        message-send-mail-function 'message-send-mail-with-sendmail)
#+end_src

* Telega
#+begin_src emacs-lisp
  (use-package telega
    :init
    (defun my/telega/olivetti () (setq-local olivetti-body-width 80))
    (defun my/telega/company-backends ()
      (setq-local company-backends
                  (append '(telega-company-username telega-company-botcmd telega-company-emoji)
                          company-backends)))
    :hook (telega-chat-mode . olivetti-mode)
    (telega-chat-mode . my/telega/olivetti)
    (telega-chat-mode . my/telega/company-backends)
    ;; installed telegram-tdlib from AUR
    :config
    (telega-mode-line-mode)
                                          ;(telega-appindicator-mode)
                                          ;(telega-notifications-mode)
    :custom (telega-server-libs-prefix "/usr")
    (telega-chat-bidi-display-reordering 'right-to-left)
    (telega-sticker-size '(10 . 24))
    (telega-emoji-use-images nil)
    (telega-symbol-checkmark "🄌")
    (telega-symbol-heavy-checkmark "⬤")
    )

#+end_src

* COMMENT Matrix Ement
#+begin_src emacs-lisp
  (use-package ement
    :straight (ement
               :type git
               :host github
               :repo "alphapapa/ement.el"))
  ;; :after org-roam ;; or :after org
  ;; :hook (org-roam . org-roam-ui-mode)
  ;; :config)
#+end_src

* Buffers and Windows
** COMMENT Workspaces (Persepective
#+begin_src emacs-lisp
  (use-package persp-mode
    :defer t
    :config
    (setq persp-keymap-prefix (kbd "SPC <tab>")))
#+end_src
** COMMENT tabspaces
#+begin_src emacs-lisp
(use-package tabspaces
  ;; use this next line only if you also use straight, otherwise ignore it. 
  ;; :straight (:type git :host github :repo "mclear-tools/tabspaces")
  :hook (after-init . tabspaces-mode) ;; use this only if you want the minor-mode loaded at startup. 
  :commands (tabspaces-switch-or-create-workspace
             tabspaces-open-or-create-project-and-workspace)
  :custom
  (tabspaces-use-filtered-buffers-as-default t)
  (tabspaces-default-tab "Default")
  (tabspaces-remove-to-default t)
  (tabspaces-include-buffers '("*scratch*"))
  (tabspaces-initialize-project-with-todo t)
  (tabspaces-todo-file-name "project-todo.org")
  ;; sessions
  (tabspaces-session t)
  (tabspaces-session-auto-restore t)
  (tab-bar-new-tab-choice "*scratch*"))
#+end_src
* Startpage
#+begin_src emacs-lisp
  (use-package dashboard
    :after solaire-mode
    :init
    (dashboard-setup-startup-hook)
    :config
    (setq dashboard-startup-banner "~/Documents/Emacs/haskell-rec.png")
    ;; Value can be
    ;; 'official which displays the official emacs logo
    ;; 'logo which displays an alternative emacs logo
    ;; 1, 2 or 3 which displays one of the text banners
    ;; "path/to/your/image.png" or "path/to/your/text.txt" which
    ;;   displays whatever image/text you would prefer

    ;; Content is not centered by default. To center, set
    (setq dashboard-center-content t)
    (setq dashboard-set-heading-icons t)
    (setq dashboard-set-file-icons t)
    (setq dashboard-items '((recents  . 5)
                            (bookmarks . 5)
                            (projects . 5)
                            (agenda . 5)))
    (setq dashboard-set-init-info t)
    (setq dashboard-projects-switch-function 'counsel-projectile-switch-project-by-name))
#+end_src

# Local Variables:
# org-highlight-latex-and-related: nil
# End:
