#+TITLE: Hane's GNU Emacs Config
#+AUTHOR: Hane
#+DESCRIPTION: Hane's personal Emacs config made with love by Haibane <3.
#+STARTUP: showeverything
#+OPTIONS: toc:2
* TABLE OF CONTENTS :toc:
- [[#load-first][LOAD FIRST]]
  - [[#startup-time][Startup Time]]
- [[#package-management][Package management]]
  - [[#package][Package]]
  - [[#use-packages][Use Packages]]
  - [[#disable-native-compilation-warnings][Disable native compilation warnings]]
  - [[#try][try]]
- [[#ui][UI]]
  - [[#Dashboard][Dashboard]]
  - [[Line wrap and line number][Line wrap and line number]]
  - [[#disable-menubar-toolbars-and-scrollbars][Disable Menubar, Toolbars and Scrollbars]]
  - [[#font][Font]]
  - [[#scratch-buffer][Scratch Buffer]]
  - [[#startup-screen][Startup screen]]
  - [[#themes][Themes]]
      - [[#Tango-dark][Tango-dark]]
      - [[#Pink-bliss-uwu][Pink-bliss-uwu]]
      - [[#Modus][Modus]]
	- [[#ef-themes][ef-themes]]
  - [[#Selection overwrite][Selection overwrite]]
- [[#smooth-scrolling][Smooth scrolling]]
  - [[#ibuffer][Ibuffer]]
- [[#window-navigation][Window Navigation]]
  - [[#mouse][Mouse]]
  - [[#windmove][Windmove]]
  - [[#winner-mode][Winner Mode]]
  - [[#repeat-mode][Repeat mode]]
- [[#help-system][Help System]]
  - [[#which-key][Which Key]]
  - [[#embark][embark]]
- [[#language-support][LANGUAGE SUPPORT]]
  - [[#elisp][Elisp]]
  - [[#org-mode][Org Mode]]
  - [[#lua][lua]]
  - [[#markdown][Markdown]]
  - [[#bbcode][BBcode]]
- [[#completion][Completion]]
  - [[#icomplete][IComplete]]
  - [[#global-completion-preview-mode][global-completion-preview-mode]]
  - [[#dabbrev][Dabbrev]]
  - [[#abbrev][Abbrev]]
  - [[#orderless][Orderless]]
  - [[#spell-checking][Spell checking]]
  - [[#hunspell][hunspell]]
- [[#ssh][SSH]]
  - [[#ssh-agency][SSH Agency]]
- [[#emacs-memory][Emacs Memory]]
- [[#magit][Magit]]
  - [[#magit-todos][Magit todos]]
- [[#benchmark-init][Benchmark-init]]
- [[#projectile][Projectile]]
  - [[#projectile-ripgrep][Projectile Ripgrep]]
- [[#crdt][Crdt]]
- [[#dokuwiki][Dokuwiki]]
  - [[#dokuwiki-mode][Dokuwiki Mode]]
- [[#etc][ETC]]
- [[#custom-file][Custom file]]
- [[#keybinds][Keybinds]]
- [[#major-modes][Major modes]]
  - [[#gnus][Gnus]]
  - [[#vterm][Vterm]]
  - [[#emms][Emms]]
  - [[#yeetube][Yeetube]]
  - [[#dired][dired]]
  - [[#marginalia][Marginalia]]
* LOAD FIRST

** Startup Time

#+begin_src emacs-lisp
   (defun efs/display-startup-time ()
     (message "Emacs loaded in %s with %d garbage collections."
	      (format "%.2f seconds"
		      (float-time
		      (time-subtract after-init-time before-init-time)))
	      gcs-done))

   (add-hook 'emacs-startup-hook #'efs/display-startup-time)
#+end_src

* Package management
** Package
#+begin_src emacs-lisp
(use-package package
:ensure nil
:defer t
:custom
;; Add MELPA and other repositories
(package-archives
  '(
    ("gnu" . "https://elpa.gnu.org/packages/")
    ("nongnu" . "https://elpa.nongnu.org/nongnu/")
    ("melpa" . "https://melpa.org/packages/")
    ("org" . "https://orgmode.org/elpa/")
))
:config
;; Initialize package system
)
#+end_src

** Use Packages
#+begin_src emacs-lisp
(setq use-package-always-ensure t)
;; (setq use-package-always-defer t)
#+end_src

** Disable native compilation warnings
#+begin_src emacs-lisp
(setq native-comp-async-report-warnings-errors nil)
#+end_src

** try
#+begin_src emacs-lisp
(use-package try
:defer t)
#+end_src
* UI
** Disable Menubar, Toolbars and Scrollbars
#+begin_src emacs-lisp
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
#+end_src

** Dashboard
#+begin_src emacs-lisp
  (use-package dashboard
    :ensure t
    :config
    (dashboard-setup-startup-hook)
    ;;Logo image
    (setq dashboard-startup-banner (cons "~/.emacs.d/logo2.jpg" "~/.emacs.d/logo.txt"))
    ;; Content is not centered by default. To center, set
    (setq dashboard-center-content t)
    ;; vertically center content
    (setq dashboard-vertically-center-content nil))

  (setq initial-buffer-choice 'dashboard-open)

#+end_src

** Line wrap and line number
#+begin_src emacs-lisp
(global-visual-line-mode t)
(global-display-line-numbers-mode t)
#+end_src

** Font
Nice font try it
#+begin_src emacs-lisp
;; (set-face-attribute 'default nil
;;  :font "FiraCode Nerd Font"
;; )
#+end_src

** Scratch Buffer
#+begin_src emacs-lisp
(setq initial-major-mode 'org-mode) ;; start in org mode
(setq initial-scratch-message nil)
#+end_src

** Startup screen
#+begin_src emacs-lisp
(setq inhibit-startup-screen t)
#+end_src

** Themes
I look down on for not using modus-vivendi-tinted
*** Tango-dark
#+begin_src emacs-lisp
    ;(load-theme 'tango-dark)
#+end_src
*** Pink-bliss-uwu
#+begin_src emacs-lisp
 ;; (use-package pink-bliss-uwu-theme
 ;;  :config
 ;;  (load-theme 'pink-bliss-uwu t)
 ;;  :custom
 ;; (pink-bliss-uwu-use-custom-font nil))
#+end_src

*** Modus
#+begin_src emacs-lisp
(use-package modus-themes
  :after ef-themes
  :ensure nil
  :demand t
  :init
  ;; Starting with version 5.0.0 of the `modus-themes', other packages
  ;; can be built on top to provide their own "Modus" derivatives.
  ;; For example, this is what I do with my `ef-themes' and
  ;; `standard-themes' (starting with versions 2.0.0 and 3.0.0,
  ;; respectively).
  ;;
  ;; The `modus-themes-include-derivatives-mode' makes all Modus
  ;; commands that act on a theme consider all such derivatives, if
  ;; their respective packages are available and have been loaded.
  ;;
  ;; Note that those packages can even completely take over from the
  ;; Modus themes such that, for example, `modus-themes-rotate' only
  ;; goes through the Ef themes (to this end, the Ef themes provide
  ;; the `ef-themes-take-over-modus-themes-mode' and the Standard
  ;; themes have the `standard-themes-take-over-modus-themes-mode'
  ;; equivalent).
  ;;
  ;; If you only care about the Modus themes, then (i) you do not need
  ;; to enable the `modus-themes-include-derivatives-mode' and (ii) do
  ;; not install and activate those other theme packages.
  (modus-themes-include-derivatives-mode 1)
  :bind
  (("<f5>" . modus-themes-load-random-dark)
   ("C-<f5>" . modus-themes-select)
   ("M-<f5>" . modus-themes-load-random-light))
  :config
  ;; Your customizations here:
  (setq modus-themes-to-toggle '(modus-operandi modus-vivendi)
	modus-themes-to-rotate modus-themes-items
	modus-themes-mixed-fonts t
	modus-themes-variable-pitch-ui t
	modus-themes-italic-constructs t
	modus-themes-bold-constructs t
	modus-themes-completions '((t . (bold)))
	modus-themes-prompts '(bold)
	modus-themes-headings
	'((agenda-structure . (variable-pitch light 2.2))
	  (agenda-date . (variable-pitch regular 1.3))
	  (t . (regular 1.15))))

  (setq modus-themes-common-palette-overrides nil)

  ;; Finally, load your theme of choice (or a random one with
  ;; `modus-themes-load-random', `modus-themes-load-random-dark',
  ;; `modus-themes-load-random-light').
  ;; (modus-themes-load-theme 'modus-operandi)
  ;; (modus-themes-load-random-dark)
)
#+end_src

**** ef-themes
#+begin_src emacs-lisp
(use-package ef-themes
  :defer nil
  :ensure t
  :init
  ;; This makes the Modus commands listed below consider only the Ef
  ;; themes.  For an alternative that includes Modus and all
  ;; derivative themes (like Ef), enable the
  ;; `modus-themes-include-derivatives-mode' instead.  The manual of
  ;; the Ef themes has a section that explains all the possibilities:
  ;;
  ;; - Evaluate `(info "(ef-themes) Working with other Modus themes or taking over Modus")'
  ;; - Visit <https://protesilaos.com/emacs/ef-themes#h:6585235a-5219-4f78-9dd5-6a64d87d1b6e>
  (ef-themes-take-over-modus-themes-mode 1)
  :config
  ;; All customisations here.
  (setq modus-themes-mixed-fonts t)
  (setq modus-themes-italic-constructs t)

  ;; Finally, load your theme of choice (or a random one with
  ;; `modus-themes-load-random', `modus-themes-load-random-dark',
  ;; `modus-themes-load-random-light').
  ;;(modus-themes-load-theme 'ef-day)
  ;;(modus-themes-load-theme 'ef-kassio)
  (modus-themes-load-theme 'ef-summer)
  ;;(modus-themes-load-theme 'ef-tritanopia-light)
  )
#+end_src

** Selection overwrite
#+begin_src emacs-lisp
(delete-selection-mode t)
#+end_src

#+begin_src emacs-lisp
(setq scroll-step 1)
(setq scroll-margin 5) ;; add few margin lines at top and bottom
#+end_src
** Ibuffer :fix:
#+begin_src emacs-lisp
(use-package ibuffer
  :bind (("C-x C-b" . ibuffer))
  :custom
  ;; (ibuffer-use-other-window nil)
  ;; Ibuffer filters
  (ibuffer-show-empty-filter-groups nil) ; don't show empty groups
  (ibuffer-saved-filter-groups
	'(("default"
	   ("org"     (or
		       (mode . org-mode)
		       (name . "^\\*Org Src")
		       (name . "^\\*Org Agenda\\*$")))
	   ("tramp"   (name . "^\\*tramp.*"))
	   ("emacs"   (or
		       (name . "^\\*scratch\\*$")
		       (name . "^\\*Messages\\*$")
		       (name . "^\\*Warnings\\*$")
		       (name . "^\\*Shell Command Output\\*$")
		       (name . "^\\*Async-native-compile-log\\*$")))
	   ("ediff"   (name . "^\\*[Ee]diff.*"))
	   ("vc"      (name . "^\\*vc-.*"))
	   ("dired"   (mode . dired-mode))
	   ("terminal" (or
			(mode . term-mode)
			(mode . shell-mode)
			(mode . eshell-mode)))
	   ("help"    (or
		       (name . "^\\*Help\\*$")
		       (name . "^\\*info\\*$")))
	   ("news"    (name . "^\\*Newsticker.*"))
	   ("gnus"    (or
		       (mode . message-mode)
		       (mode . gnus-group-mode)
		       (mode . gnus-summary-mode)
		       (mode . gnus-article-mode)
		       (name . "^\\*Group\\*")
		       (name . "^\\*Summary\\*")
		       (name . "^\\*Article\\*")
		       (name . "^\\*BBDB\\*")))
	   ("chat"    (or
		       (mode . rcirc-mode)
		       (mode . erc-mode)
		       (name . "^\\*rcirc.*")
		       (name . "^\\*ERC.*"))))))
   :config
   (ibuffer-switch-to-saved-filter-groups "default")

)

#+end_src

* Window Navigation
** Mouse
#+begin_src emacs-lisp
(setq mouse-autoselect-window t)
#+end_src
** Windmove
#+begin_src emacs-lisp
  (use-package windmove
  :custom
  (windmove-create-window 1)
  :config
  (windmove-default-keybindings)
  (windmove-default-keybindings 'ctrl))
#+end_src

** Winner Mode
#+begin_src emacs-lisp
(winner-mode 1)
#+end_src

** Repeat mode
#+begin_src emacs-lisp
(use-package repeat
:init (repeat-mode)
:bind (("C-." . repeat)))
#+end_src

* Help System
** Which Key
#+begin_src emacs-lisp
(use-package which-key
  :custom
  (which-key-idle-delay 0.001) ;; a vaule of zero cause issues never set it to zero
  :config
  (which-key-mode 1))
#+end_src


** embark
Shows all actions on point
NOTE: Meh.
#+begin_src emacs-lisp
  (use-package embark
  :defer t)
#+end_src


* LANGUAGE SUPPORT
Emacs has built-in programming language modes for Lisp, Scheme, DSSSL, Ada, ASM, AWK, C, C++, Fortran, Icon, IDL (CORBA), IDLWAVE, Java, Javascript, M4, Makefiles, Metafont, Modula2, Object Pascal, Objective-C, Octave, Pascal, Perl, Pike, PostScript, Prolog, Python, Ruby, Simula, SQL, Tcl, Verilog, and VHDL.  Other languages will require you to install additional modes.

** Elisp
TODO: No funciona?
#+begin_src emacs-lisp
;; (electric-pair-mode 1) ;; maybe use M-( instead you can also embed word by (seclting) them
(use-package rainbow-delimiters
:vc (:url https://github.com/Fanael/rainbow-delimiters.git)
:hook (prog-mode . rainbow-delimiters-mode))
#+end_src

** Org Mode

*** Show Images in Org Mode
#+begin_src emacs-lisp
;; show images in org
(setq org-startup-with-inline-images t)
#+end_src

*** Enabling Table of Contents :fix:
#+begin_src emacs-lisp
(use-package toc-org
  :disabled
  :commands toc-org-enable
  ;; :init (add-hook 'org-mode-hook 'toc-org-enable))
  :hook (org-mode . toc-org-enable))
#+end_src

*** Enabling Org Bullets
Org-bullets gives us attractive bullets rather than asterisks.

#+begin_src emacs-lisp
  ;;(add-hook 'org-mode-hook 'org-indent-mode)
  ;;(use-package org-bullets)
  ;;(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
#+end_src

*** Diminish Org Indent Mode
Removes "Ind" from showing in the modeline.

#+begin_src emacs-lisp
(eval-after-load 'org-indent '(diminish 'org-indent-mode))

#+end_src

*** Org Level Headers
#+begin_src emacs-lisp
  (custom-set-faces
   '(org-level-1 ((t (:inherit outline-1 :height 1.7))))
   '(org-level-2 ((t (:inherit outline-2 :height 1.6))))
   '(org-level-3 ((t (:inherit outline-3 :height 1.5))))
   '(org-level-4 ((t (:inherit outline-4 :height 1.4))))
   '(org-level-5 ((t (:inherit outline-5 :height 1.3))))
   '(org-level-6 ((t (:inherit outline-5 :height 1.2))))
   '(org-level-7 ((t (:inherit outline-5 :height 1.1)))))
#+end_src

*** Org Todo
#+begin_src emacs-lisp
  (setq org-todo-keywords
	  (quote ((sequence "TODO" "NEXT" "DONE" "PROJECTDONE" "WAITING" "SOMEDAY" "CANCELLED"))))
    (setq org-todo-keyword-faces
	  (quote (("TODO" :foreground "lime green" :weight bold)
		  ("NEXT" :foreground "cyan" :weight bold)
		  ("DONE" :foreground "dim gray" :weight bold)
		  ("PROJECTDONE" :foreground "dim gray" :weight bold)
		  ("WAITING" :foreground "tomato" :weight bold)
		  ("SOMEDAY" :foreground "magenta" :weight bold)
		  ("CANCELLED" :foreground "dim gray" :weight bold)
		("NOTE" :foreground "pink" :weight bold))))
#+end_src

This code is pointles sense we are not using hl-todo i inserted it here to make the job of porting it the src block that above easier sense i cant really know which one you want and which ones you dont want
#+begin_src emacs-lisp
  (setq hl-todo-keyword-faces
	'(("HOLD" . "#d0bf8f")
	  ("TODO" . hl-todo-custom-face)
		  ("todo" . hl-todo-custom-face)
	  ("NEXT" . "#dca3a3")
	  ("THEM" . "#dc8cc3")
	  ("PROG" . "#7cb8bb")
	  ("OKAY" . "#7cb8bb")
	  ("DONT" . "#5f7f5f")
	  ("FAIL" . "#8c5353")
	  ("DONE" . "#afd8af")
	  ("NOTE"   . "#d0bf8f")
	  ("KLUDGE" . "#d0bf8f")
	  ("HACK"   . "#d0bf8f")
	  ("TEMP"   . "#d0bf8f")
	  ("FIXME"  . "#cc9393")
	  ("XXX+"   . "#cc9393")))
#+end_src
*** Source Code Block Tag Expansion
Org-tempo is not a separate package but a module within org that can be enabled.  Org-tempo allows for '<s' followed by TAB to expand to a begin_src tag.  Other expansions available include:

| Typing the below + TAB | Expands to ...                          |
|------------------------+-----------------------------------------|
| <a                     | '#+BEGIN_EXPORT ascii' … '#+END_EXPORT  |
| <c                     | '#+BEGIN_CENTER' … '#+END_CENTER'       |
| <C                     | '#+BEGIN_COMMENT' … '#+END_COMMENT'     |
| <e                     | '#+BEGIN_EXAMPLE' … '#+END_EXAMPLE'     |
| <E                     | '#+BEGIN_EXPORT' … '#+END_EXPORT'       |
| <h                     | '#+BEGIN_EXPORT html' … '#+END_EXPORT'  |
| <l                     | '#+BEGIN_EXPORT latex' … '#+END_EXPORT' |
| <q                     | '#+BEGIN_QUOTE' … '#+END_QUOTE'         |
| <s                     | '#+BEGIN_SRC' … '#+END_SRC'             |
| <v                     | '#+BEGIN_VERSE' … '#+END_VERSE'         |

#+begin_src emacs-lisp
(require 'org-tempo)
#+end_src

** lua
#+begin_src emacs-lisp
(use-package lua-mode
:defer t)
#+end_src

** Markdown
#+begin_src emacs-lisp
(use-package markdown-mode
  :defer t
  :custom
  (markdown-command "multimarkdown"))
#+end_src

** BBcode
Check the [[https://www.emacswiki.org/emacs/BbCode][Wiki]]
#+begin_src emacs-lisp
(use-package bbcode-mode
  :disabled t
  :vc (:url "https://github.com/lassik/emacs-bbcode-mode.git"))
#+end_src

* Completion
** IComplete
#+begin_src emacs-lisp
  ;; (fido-mode 1)
  ;; (fido-vertical-mode 1) ;; for veritcal fido
  ;; (setq resize-mini-windows nil) ;; if you disabled fido-vertical-mode uncomment this so standard fido doesnt resize the echo area HOWEVER if you are using fido-vertical-mode and enabled this it will break
  (use-package icomplete
    :bind (:map icomplete-minibuffer-map
		("C-n" . icomplete-forward-completions)
		("C-p" . icomplete-backward-completions)
		("<down>" . icomplete-forward-completions)
		("<up>" . icomplete-backward-completions)
		;;("C-v" . icomplete-vertical-toggle)
		("RET" . icomplete-force-complete-and-exit)
		("C-j" . exit-minibuffer)) ;; So we can exit commands like `multi-file-replace-regexp-as-diff'

    :custom
    (fido-vertical-mode 1)
    (icomplete-delay-completions-threshold 0)
    (icomplete-compute-delay 0)
    (icomplete-show-matches-on-no-input t)
    ;; (icomplete-hide-common-prefix nil)
    (icomplete-prospects-height 10)
    ;; (icomplete-separatorq " . ")
    (icomplete-with-completion-tables t)
    (icomplete-in-buffer t)
    (icomplete-max-delay-chars 0)
    (icomplete-scroll t)


    (icomplete-vertical-in-buffer-adjust-list t)
    (icomplete-vertical-render-prefix-indicator t)
    ;; (icomplete-vertical-selected-prefix-indicator   " @ ")
    ;; (icomplete-vertical-unselected-prefix-indicator "   ")
    :config
    ;; hide the minibuffer
    (advice-add 'completion-at-point
		:after #'minibuffer-hide-completions)

  )
#+end_src

** global-completion-preview-mode
This is what shows an unopinionated autocomplete suggestion. I love this implementation
#+begin_src emacs-lisp
(use-package completion-preview
:config
(global-completion-preview-mode)
(push 'org-self-insert-command completion-preview-commands))
#+end_src

** Dabbrev
#+begin_src emacs-lisp
  (use-package dabbrev
    ;; Swap M-/ and C-M-/
    :bind (("M-/" . dabbrev-completion)
  	   ("C-M-/" . dabbrev-expand))
    :config
    (add-to-list 'dabbrev-ignored-buffer-regexps "\\` ")
    (add-to-list 'dabbrev-ignored-buffer-modes 'authinfo-mode)
    (add-to-list 'dabbrev-ignored-buffer-modes 'doc-view-mode)
    (add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode)
    (add-to-list 'dabbrev-ignored-buffer-modes 'tags-table-mode))
  
#+end_src

** Abbrev
#+begin_src emacs-lisp
(use-package abbrev
    :ensure nil
    :custom
    (save-abbrevs nil)
    :config
    (define-abbrev-table 'global-abbrev-table
      '(;; Arrows
        ("ra" "→")
        ("la" "←")
        ("ua" "↑")
        ("da" "↓")

        ;; Emojis for context markers
        ("todo"  "👷 TODO:")
        ("fixme" "🔥 FIXME:")
        ("note"  "📎 NOTE:")
        ("hack"  "👾 HACK:")
        ("pinch"  "🤌")
        ("smile"  "😄")
        ("party" "🎉")
        ("up"  "☝️")
        ("applause" "👏")
        ("manyapplauses" "👏👏👏👏👏👏👏👏")
        ("heart" "❤️")

        ;; NerdFonts
        ("nerdfolder" " ")
        ("nerdgit" "")
        ("nerdemacs" "")

        ;; HTML
        ("nb" "&nbsp;")
        ("lt" "&lt;")      ;; <
        ("gt" "&gt;")      ;; >
        ("le" "&le;")      ;; ≤
        ("ge" "&ge;")      ;; ≥
        ("ap" "&apos;")    ;; '
        ("laa" "&laquo;")  ;; «
        ("raa" "&raquo;")  ;; »
        ("co" "&copy;")    ;; ©
        ("tm" "&trade;")   ;; ™
        ("em" "&mdash;")   ;; —
        ("en" "&ndash;")   ;; –
        ("dq" "&quot;")    ;; "
        ("html" "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Document</title>\n</head>\n<body>\n\n</body>\n</html>")

        ;; Utils
        ("isodate" ""
         (lambda () (insert (format "%s" (format-time-string "%Y-%m-%dT%H:%M:%S")))))

        ("uuid" ""
         (lambda () (insert (org-id-uuid))))

        ;; Markdown
        ("cb" "```@\n\n```"
         (lambda () (search-backward "@") (delete-char 1)))

        ;; ORG
        ("ocb" "#+BEGIN_SRC @\n\n#+END_SRC"
         (lambda () (search-backward "@") (delete-char 1)))
        ("oheader" "#+TITLE: ###1###\n#+AUTHOR: ###2###\n#+EMAIL: ###3###\n#+OPTIONS: toc:nil\n"
         emacs-solo/abbrev--replace-placeholders)

        ;; JS/TS snippets
        ("imp" "import { ###1### } from '###2###';"
         emacs-solo/abbrev--replace-placeholders)
        ("fn" "function ###1### () {\n ###@### ;\n};"
         emacs-solo/abbrev--replace-placeholders)
        ("clog" "console.log(\">>> LOG:\", { ###@### })"
         emacs-solo/abbrev--replace-placeholders)
        ("cwarn" "console.warn(\">>> WARN:\", { ###@### })"
         emacs-solo/abbrev--replace-placeholders)
        ("cerr" "console.error(\">>> ERR:\", { ###@### })"
         emacs-solo/abbrev--replace-placeholders)
        ("afn" "async function() {\n  \n}"
         (lambda () (search-backward "}") (forward-line -1) (end-of-line)))
        ("ife" "(function() {\n  \n})();"
         (lambda () (search-backward ")();") (forward-line -1) (end-of-line)))
        ("esdeps" "// eslint-disable-next-line react-hooks/exhaustive-deps"
         (lambda () (search-backward ")();") (forward-line -1) (end-of-line)))
        ("eshooks" "// eslint-disable-next-line react-hooks/rules-of-hooks"
         (lambda () (search-backward ")();") (forward-line -1) (end-of-line)))

        ;; React/JSX
        ("rfc" "const ###1### = () => {\n  return (\n    <div>###2###</div>\n  );\n};"
         emacs-solo/abbrev--replace-placeholders))))
#+end_src

** Orderless
#+begin_src emacs-lisp
  ;; Optionally use the `orderless' completion style.
  (use-package orderless
    :disabled t
    :vc (:url https://github.com/oantolin/orderless.git)
    :custom
    ;; (orderless-style-dispatchers '(orderless-affix-dispatch))
    ;; (orderless-component-separator #'orderless-escapable-split-on-space)
    (completion-styles '(orderless basic))
    (completion-category-overrides '((file (styles partial-completion))))
    (completion-category-defaults nil) ;; Disable defaults, use our settings
    (completion-pcm-leading-wildcard t)) ;; Emacs 31: partial-completion behaves like substring
#+end_src


** Spell checking
*** Cape
#+begin_src emacs-lisp
(use-package cape :ensure t
  ;; For nixos only
   :init
   ;; Add dictionary completion
   (add-to-list 'completion-at-point-functions #'cape-dict)
  ;; :custom
  ;; (cape-dict-file "/run/current-system/sw/share/hunspell/en_US.dic") ;; For nixos only
)

#+end_src

** hunspell
install hunspell for spell checking to work
#+begin_src emacs-lisp
(setq ispell-program-name "hunspell")
(setq ispell-dictionary "en_US")
#+end_src

* SSH
** SSH Agency
#+begin_src emacs-lisp
(use-package ssh-agency
:defer t)
#+end_src

* Emacs Memory
#+begin_src emacs-lisp
(recentf-mode 1) ;; enables M-x recentf-open-files
(setq history-length 25) ;; Limit history length to speed up emacs startup time this only effect every history lists that don’t specify their own maximum lengths
(save-place-mode 1) ;; Remember and restore the last cursor location of opened files
(savehist-mode 1) ;; Save what you enter into minibuffer prompts
#+end_src

* Magit :soy:
#+begin_src emacs-lisp
(use-package magit
:defer t)
#+end_src

** Magit todos :soy:
#+begin_src emacs-lisp
(use-package magit-todos
  :after magit
  :commands (magit-todos-mode)
  :custom
  (magit-todos-nice nil)
  ;; ((magit-todos-git-grep-extra-args (list "-n")))
  (magit-todos-scanner 'magit-todos--scan-with-rg)
  ;; (magit-todos-depth 100)
  :config
  (magit-todos-mode 1))
#+end_src


* Projectile :soy:
#+begin_src emacs-lisp
(use-package projectile
 :defer t
 :custom
 ;;Allowing per project compilation command
 (projectile-per-project-compilation-buffer t)
 :config
 (projectile-global-mode))
#+end_src

** Projectile Ripgrep :soy:
#+begin_src emacs-lisp
(use-package projectile-ripgrep
  :after projectile)
#+end_src

* Crdt
#+begin_src emacs-lisp
(use-package crdt
  :defer t)
#+end_src
* Dokuwiki
#+begin_src emacs-lisp
(use-package dokuwiki
  :defer t
  :custom
  (dokuwiki-xml-rpc-url "https://wiki.roboces.dev/lib/exe/xmlrpc.php")
  (dokuwiki-login-user-name "superuser"))
#+end_src

** Dokuwiki Mode
#+begin_src emacs-lisp
(use-package dokuwiki-mode
  :after dokuwiki)
#+end_src
* ETC
#+begin_src emacs-lisp
(setq back-directory-alist '(("." . "~/.config/emacs/backups/"))) ;; so you dont get backup files ending with ~ in the same folder as the file NOTE:maybe there is a way to use the $EMACSDIR instead of Specifying it here
(setq use-dialog-box nil) ;; Don't pop up UI dialogs when prompting
(global-auto-revert-mode 1) ;; Revert buffers when the underlying file has changed
(setq global-auto-revert-non-file-buffers t ) ;; Revert Dired and other buffers
(context-menu-mode 1) ;; right click menu
(xterm-mouse-mode 1) ;; mouse support in the terminal
(setq echo-keystrokes 0.001) ;; make keybinds appear faster after the echo area however overwritten by which-key-idle-delay
;; (global-subword-mode 1) ;; for SubWords!!
(auto-save-visited-mode 1) ;; read the documentation to get the behavior you want to be exact both auto-save-visited-interval and auto-save-visited-predicate
#+end_src

* Custom file
Move customization variables to a separate file and load it
#+begin_src emacs-lisp
(setq custom-file (locate-user-emacs-file "custom.el"))
(load custom-file 'noerror 'nomessage)
#+end_src


* Keybinds
yes this is very silly but also very useful for setting generic keybinds

#+begin_src emacs-lisp
  ;;(use-package emacs
  ;;:disabled t
  ;;:bind
  ;; keybinds are defined here
  ;;)
#+end_src

  * Keybinds
bind repeat to a better key
#+begin_src emacs-lisp
;;(global-set-key (kbd "C-.") #'repeat)
#+end_src
#+begin_src emacs-lisp
  (defun enlarge-window-minibuf ()
    (interactive)
    (let ((are 0))
      (setq are (read-from-minibuffer "Size offset: " nil nil 1 nil 0 1))
      (enlarge-window are)))

  (defun move-to-window-line-minibuf ()
  (interactive)
  (let ((are 0))
    (setq are (read-from-minibuffer "Line offset: " nil nil 1 nil 0 1))
    (move-to-window-line are)))

  ;;See: https://stackoverflow.com/questions/683425/globally-override-key-binding-in-emacs
  (defvar my-keys-minor-mode-map
    (let ((map (make-sparse-keymap)))
      ;; Windmove/winner mappings
      (define-key map (kbd "C-c h")  'windmove-left)
      (define-key map (kbd "C-c j")  'windmove-down)
      (define-key map (kbd "C-c k")  'windmove-up)
      (define-key map (kbd "C-c l")  'windmove-right)
      (define-key map (kbd "C-c u")  'winner-undo)

      ;; Map inverse transpose
      (define-key map (kbd "C-S-t") (lambda () (interactive) (transpose-chars -1)))

      ;; Use regex search tools
      (define-key map (kbd "C-s") 'isearch-forward-regexp)
      (define-key map (kbd "C-r") 'isearch-backward-regexp)

      ;; Kill whole line
      (define-key map (kbd "C-z") 'kill-whole-line)

      ;;Function key shenanigans
      (define-key map [f5] 'eval-buffer)
      (define-key map [f6] 'comment-region)
      (define-key map [f9] (lambda () (interactive) (find-file user-init-file)) )
      (define-key map [f8] 'projectile-find-file)
      (define-key map [f7] 'projectile-compile-project)
      (define-key map [f10] (lambda () (interactive) (kill-buffer "*compilation*")))

      ;; info-apropos mapping
      (define-key map (kbd "C-c a") 'info-apropos)

      ;; Rectangle mark mode and insert
      (define-key map (kbd "C-c SPC") 'string-insert-rectangle)
      (define-key map (kbd "C-x SPC") 'rectangle-mark-mode)

      ;;frame size control
      (global-set-key (kbd "C-x C-c") 'toggle-frame-maximized)

      ;; Enlarge/shrink windows
      (define-key map (kbd "C-c w") 'enlarge-window-minibuf)

      ;;Move one vertical amount of lines / end - beginning buffer
      (define-key map (kbd "C-c e") 'move-to-window-line-minibuf)

      ;;emms bindings
      (define-key map (kbd "C-c +") 'emms-volume-mode-plus)
      (define-key map (kbd "C-c -") 'emms-volume-mode-minus)
      (define-key map (kbd "C-c )") 'emms-next)
      (define-key map (kbd "C-c (") 'emms-previous)
      (define-key map (kbd "C-c *") 'emms-pause)

      ;; On-home-row cycling through buffers
      (define-key map (kbd "C-c n") 'previous-buffer)
      (define-key map (kbd "C-c m") 'next-buffer)

      ;; On-home-row point movement
      ;; (define-key map (kbd "C-; j") 'next-line)
      ;; (define-key map (kbd "C-; l") 'previous-line)
      ;; (define-key map (kbd "C-; ;") 'forward-char)
      ;; (define-key map (kbd "C-; ñ") 'forward-char)
      ;; (define-key map (kbd "C-; j") 'backward-char)

      ;; Move forward word by word
      ;; (define-key map (kbd "C-f") 'forward-word)
      ;; (define-key map (kbd "C-b") 'backward-word)

      ;; Map delete/backspace
      ;; (define-key map (kbd "C-S-d") (lambda () (interactive) (backward-delete-char-untabify 1)))

      ;; Map RET
      ;;(define-key map (kbd  "C-i") (lambda () (interactive) (newline)))

      ;; TODO: Remap up/downcase to region instead of word - not working
      ;; (put 'downcase-region 'disabled nil)
      ;; (put 'upcase-region 'disabled nil)
      ;; (define-key map (kbd "M-S-l") (lambda () (interactive) (upcase-region)))
      ;; (define-key map (kbd "M-l") (lambda () (interactive) (downcase-region)))

      ;; Map scroll line by line
      ;;(define-key map (kbd "M-i") (lambda () (interactive) (scroll-up   1)) )
      ;;(define-key map (kbd "M-p") (lambda () (interactive) (scroll-down 1)) )

      ;; Old-school cycle windows
      ;; (define-key map (kbd "C-x C-u") (lambda () (interactive) (other-window -1)))
      ;; (define-key map (kbd "C-x C-o") (lambda () (interactive) (other-window 1)))

      ;; Dired-jump and delete-blank-lines
      ;;(define-key map (kbd "C-x u") 'dired-jump)
      ;;(define-key map (kbd "C-x o")  'delete-blank-lines)

  	  ;;; On-home-row cycling through buffers
      ;; (define-key map (kbd "C-x C-j") 'previous-buffer)
      ;; (define-key map (kbd "C-x C-ñ") 'next-buffer)
      ;; (define-key map (kbd "C-x C-;") 'next-buffer)


      ;;Undo/redo and kill line
      ;; (define-key map (kbd "C-n") 'undo)
      ;; (define-key input-decode-map [?\C-m] [C-m])
      ;; (define-key map (kbd "<C-m>") 'undo-redo)

      ;;zap-to-char M-z, toggle-input-method C-\, transpose-chars C-t
      ;; (define-key map (kbd "M-b") 'backward-char)
      ;; (define-key map (kbd "M-f") 'forward-char)

      ;; (global-set-key (kbd "C-.") 'end-of-buffer)
      ;; (global-set-key (kbd "M-.") 'beginning-of-buffer)

      map)
    "my-keys-minor-mode keymap.")

  (define-minor-mode my-keys-minor-mode
    "A minor mode so that my key settings override annoying major modes."
    :init-value t
    :lighter " my-keys")

  (my-keys-minor-mode 1)
#+end_src

* Major modes
** Gnus
for when you join the cult 😈
#+begin_src emacs-lisp
  (use-package gnus
    :disabled
    :defer t
    :custom

    ;; Make Gnus more asynchronous
    (gnus-asynchronous t)

    ;; Sane newsrc management
    (gnus-always-read-dribble-file t)
    (gnus-save-newsrc-file nil)
    (gnus-read-newsrc-file nil)
    (gnus-save-newsrc-file nil)
    (gnus-read-newsrc-file nil)
    (gnus-startup-file "~/.config/emacs/newsrc")

    ;; Make gnus remember everything
    (gnus-registry-use t)
    (gnus-registry-track-extra t)
    (gnus-suppress-duplicates t) ;; check Message-ID to make sure you only read an artical once
    (mm-text-html-renderer 'gnus-w3m)

    ;; Enable image support
    (gnus-inhibit-images nil)
    (gnus-blocked-images nil)

    ;; Set scoring for things other than FROM: header
    (gnus-extra-headers '(To Cc X-Feedname Newsgroups Keywords) nnmail-extra-headers gnus-extra-headers)
    (nnmail-debug-splitting t)
    (gnus-search-use-parsed-queries t) ;; same syntax for all search backends
    ;; Make Gnus backend agnostic
    (gnus-select-method '(nnnil))
    ;; Backends
    (gnus-secondary-select-methods
      '(;; (nntp "news.gmane.io") ;; best usenet sever ever can be used to view mailing lists without actualy joining them disabled by default for load time
	(nnmaildir "" ;; The best way to view rss in Gnus is via fethcing them from sfeed then piping into mbox file then using fdm script to turn every feed into a maildir folder dm me about it
	  (directory "~/mail/rss/")
	  (nnmaildir-get-new-mail t))))
    :bind
    (("C-x g" . gnus)))
#+end_src
** Vterm
#+begin_src emacs-lisp
  (use-package vterm
  :defer t)
#+end_src
*** Eshell vterm
#+begin_src emacs-lisp
  (use-package eshell-vterm
  :after eshell
  :config
  (eshell-vterm-mode 1)
  (add-to-list 'eshell-visual-commands "htop")
  (add-to-list 'eshell-visual-commands "ssh")
  (add-to-list 'eshell-visual-commands "nvim")
  (add-to-list 'eshell-visual-commands "less")
  (add-to-list 'eshell-visual-commands "watch")
  (add-to-list 'eshell-visual-commands "yazi")
  (add-to-list 'eshell-visual-commands "top")
  (add-to-list 'eshell-visual-commands "btop")
  (add-to-list 'eshell-visual-commands "wiremix")
)
#+end_src
** Emms
Your Emacs media Centor and manager (or just a fany .m3a files client if you want that way)
#+begin_src emacs-lisp
  (use-package emms
    :defer t
    :init
    ;; set this function as your browser for sites like youtube
    (defun my-browse-url-emms (url &rest _args)
    "Play URL with EMMS."
    (emms-add-url url))
    :config
    (emms-all)
    ;; this enables everything that package can do which makes it really heavy and slow but its recommended at the start to know all the features of the package
    (setq-default
     emms-player-list '(emms-player-mpv)
     emms-player-mpv-environment '("PULSE_PROP_media.role=music")
     emms-volume-change-function 'emms-volume-mpv-change
     emms-volume-mpv-method 'smart

     emms-info-functions '(emms-info-native))

    ;; (emms-default-players)

    ;; use this if you want to set mpv and only mpv as your default player
    ;;(add-to-list 'emms-player-list 'emms-player-mpv)
    (emms-history-load)
  )
#+end_src

** Yeetube
#+BEGIN_SRC emacs-lisp
  (use-package yeetube
    :disabled nil
    :defer t
    :init (define-prefix-command 'my/yeetube-map)
    ;;(setf yeetube-filter "Views")
    (setf yeetube-filter "Likes")
    :config
    (setf yeetube-play-function #'emms-play-url)
    (setf yeetube-play-function #'browse-url)
    :bind (("C-x y" . 'my/yeetube-map)
	    :map my/yeetube-map
		  ("s" . 'yeetube-search)
		  ("b" . 'yeetube-play-saved-video)
		  ("d" . 'yeetube-download-videos)
		  ("p" . 'yeetube-mpv-toggle-pause)
		  ("v" . 'yeetube-mpv-toggle-video)
		  ("V" . 'yeetube-mpv-toggle-no-video-flag)
		  ("k" . 'yeetube-remove-saved-video)))

#+END_SRC

** dired
#+begin_src emacs-lisp
(setq image-animate-loop t) ;; gif support in emacs
(add-hook 'image-mode-hook #'image-toggle-animation)
#+end_src

*** Dired Preview
#+begin_src emacs-lisp
(use-package dired-preview
;;:disabled t
:after dired
:custom
;; Default values for demo purposes
(dired-preview-delay 0.001) ;; cant be a 0 or it will translate to 0.1
(dired-preview-max-size (expt 2 20))
(dired-preview-ignored-extensions-regexp
	(concat "\\."
		"\\(gz\\|"
		"zst\\|"
		"tar\\|"
		"xz\\|"
		"rar\\|"
		"zip\\|"
		"iso\\|"
		"epub"
		"\\)"))
:config
;; Enable `dired-preview-mode' in a given Dired buffer or do it
;; globally:
(dired-preview-global-mode 1)
)
#+end_src

** Marginalia
#+begin_src emacs-lisp
;; Enable rich annotations using the Marginalia package
(use-package marginalia
  ;; Bind `marginalia-cycle' locally in the minibuffer.  To make the binding
  ;; available in the *Completions* buffer, add it to the
  ;; `completion-list-mode-map'.
  :bind (:map minibuffer-local-map
	 ("M-A" . marginalia-cycle))

  ;; The :init section is always executed.
  :init

  ;; Marginalia must be activated in the :init section of use-package such that
  ;; the mode gets enabled right away. Note that this forces loading the
  ;; package.
  (marginalia-mode))
#+end_src
