#+TITLE:LM's Emacs Config
#+Author: Liam Malone (LM)
#+DESCRIPTION: LM's personal Emacs config
#+STARTUP: showeverything
#+OPTIONS: toc:2

* TABLE OF CONTENTS :toc:
- [[#important-programs-to-load-first][IMPORTANT PROGRAMS TO LOAD FIRST]]
  - [[#elpaca-package-manager][Elpaca Package Manager]]
  - [[#load-evil-mode][Load Evil Mode]]
  - [[#general-keybindings][General Keybindings]]
- [[#all-the-icons][ALL THE ICONS]]
- [[#autosave][AUTOSAVE]]
- [[#company][COMPANY]]
- [[#dashboard][DASHBOARD]]
- [[#diminish][DIMINISH]]
- [[#drag-stuff][DRAG-STUFF]]
- [[#flycheck][FLYCHECK]]
- [[#fonts][FONTS]]
  - [[#setting-the-font-face][Setting The Font Face]]
  - [[#zoom-inout][Zoom In/Out]]
- [[#gnuplot][GNUPLOT]]
- [[#image-dir-ed][IMAGE DIR-ED]]
- [[#indentingtabs][INDENTING/TABS]]
- [[#ligatures][LIGATURES]]
- [[#markdown-mode][MARKDOWN MODE]]
- [[#org-download][ORG DOWNLOAD]]
- [[#pulse][PULSE]]
- [[#pdf-tools][PDF TOOLS]]
- [[#projectile][PROJECTILE]]
- [[#rainbow-mode][RAINBOW MODE]]
- [[#reload-emacs][RELOAD EMACS]]
- [[#shells-and-terminals][SHELLS AND TERMINALS]]
  - [[#eshell][ESHELL]]
- [[#sudo-edit][SUDO EDIT]]
- [[#theme][THEME]]
- [[#transparency][TRANSPARENCY]]
- [[#gui-tweaks][GUI TWEAKS]]
  - [[#disable-menubar-toolbars-and-scrollbars][Disable menubar, toolbars and scrollbars]]
  - [[#display-line-numbers-and-truncated-lines][Display line numbers and truncated lines]]
- [[#ivy-counsel][IVY (COUNSEL)]]
- [[#language-support][LANGUAGE SUPPORT]]
- [[#org-mode][ORG MODE]]
  - [[#enabling-table-of-contents][Enabling table of contents]]
  - [[#enabling-org-bullets][Enabling org bullets]]
  - [[#source-code-block-tag-expansion][SOURCE CODE BLOCK TAG EXPANSION]]
  - [[#pdf-links][Pdf links]]
- [[#which-key][WHICH-KEY]]

* IMPORTANT PROGRAMS TO LOAD FIRST
** Elpaca Package Manager
#+begin_src emacs-lisp
(defvar elpaca-installer-version 0.6)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
			:ref nil
			:files (:defaults (:exclude "extensions"))
			:build (:not elpaca--activate-package)))
(let* ((repo  (expand-file-name "elpaca/" elpaca-repos-directory))
 (build (expand-file-name "elpaca/" elpaca-builds-directory))
 (order (cdr elpaca-order))
 (default-directory repo))
  (add-to-list 'load-path (if (file-exists-p build) build repo))
  (unless (file-exists-p repo)
    (make-directory repo t)
    (when (< emacs-major-version 28) (require 'subr-x))
    (condition-case-unless-debug err
  (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
	   ((zerop (call-process "git" nil buffer t "clone"
				 (plist-get order :repo) repo)))
	   ((zerop (call-process "git" nil buffer t "checkout"
				 (or (plist-get order :ref) "--"))))
	   (emacs (concat invocation-directory invocation-name))
	   ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
				 "--eval" "(byte-recompile-directory \".\" 0 'force)")))
	   ((require 'elpaca))
	   ((elpaca-generate-autoloads "elpaca" repo)))
      (kill-buffer buffer)
    (error "%s" (with-current-buffer buffer (buffer-string))))
((error) (warn "%s" err) (delete-directory repo 'recursive))))
  (unless (require 'elpaca-autoloads nil t)
    (require 'elpaca)
    (elpaca-generate-autoloads "elpaca" repo)
    (load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))

;; Install use-package support
(elpaca elpaca-use-package
  ;; Enable :elpaca use-package keyword.
  (elpaca-use-package-mode)
  ;; Assume :elpaca t unless otherwise specified.
  (setq elpaca-use-package-by-default t))

;; Block until current queue processed.
(elpaca-wait)

;;When installing a package which modifies a form used at the top-level
;;(e.g. a package which adds a use-package key word),
;;use `elpaca-wait' to block until that package has been installed/configured.
;;For example:
;;(use-package general :demand t)
;;(elpaca-wait)

;;Turns off elpaca-use-package-mode current declartion
;;Note this will cause the declaration to be interpreted immediately (not deferred).
;;Useful for configuring built-in emacs features.
;;(use-package emacs :elpaca nil :config (setq ring-bell-function #'ignore))

;; Don't install anything. Defer execution of BODY
;;(elpaca nil (message "deferred"))
#+end_src

** Load Evil Mode

#+begin_src emacs-lisp
  ;; Expands to: (elpaca evil (use-package evil :demand t))
  (use-package evil
      :init      ;; tweak evil's configuration before loading it
      (setq evil-want-integration t) ;; This is optional since it's already set to t by default.
      (setq evil-respect-visual-line-mode t)
      (setq evil-want-keybinding nil)
      (setq evil-vsplit-window-right t)
      (setq evil-split-window-below t)
      (evil-mode))
    (use-package evil-collection
      :after evil
      :config
      (setq evil-collection-mode-list '(dashboard dired ibuffer))
      (evil-collection-init))
  ;; set C-u for scrolling up... not sure why this has to be manual
  (global-set-key (kbd "C-u") 'evil-scroll-up)
#+end_src


** General Keybindings

#+begin_src emacs-lisp

  (use-package general
      :config
      (general-evil-setup)
      ;; set 'SPC' as global leader key
      (general-create-definer lm/leader-keys
        :states '(normal insert visual emacs)
        :keymaps 'override
        :prefix "SPC" ;; set leader
        :global-prefix "M-SPC") ;; access leader in insert mode

      (lm/leader-keys
          "b" '(:ignore t :wk "buffer")
          "b b" '(switch-to-buffer :wk "Switch buffer")
          "b i" '(ibuffer :wk "Ibuffer")
          "b k" '(kill-this-buffer :wk "Kill this buffer")
          "b n" '(next-buffer :wk "Next buffer")
          "b p" '(previous-buffer :wk "Previous buffer")
          "b r" '(revert-buffer :wk "Reload buffer"))

      (lm/leader-keys
          "e" '(:ignore t :wk "Eshell/Evaluate")
          "e b" '(eval-buffer :wk "Evaluate elisp in buffer")
          "e d" '(eval-defun :wk "Evaluate defun containing or after point")
          "e e" '(eval-expression :wk "Evaluate an elisp expression")
          "e l" '(eval-last-sexp :wk "Evaluate elisp expression before point")
          "e r" '(eval-region :wk "Evaluate elisp in region")
          "e h" '(counsel-esh-history :wk "Eshell history")
          "e s" '(eshell :wk "Eshell"))

      (lm/leader-keys
          "SPC" '(counsel-M-x :wk "Counsel M-x")
          "." '(find-file :wk "Find file")
          "f c" '((lambda () (interactive) (find-file "~/.config/emacs/config.org")) :wk "Edit emacs config")
          "f r" '(counsel-recentf :wk "Find recent files")
          "TAB TAB" '(comment-line :wk "Comment lines"))

      (lm/leader-keys
          "h" '(:ignore t :wk "Help")
          "h f" '(describe-function :wk "Describe function")
          "h v" '(describe-variable :wk "Describe variable")
          "h r r" '(reload-init-file :wk "Reload emacs config"))
          ;; "h r r" '((lambda () (interactive) (load-file user-init-file)) :wk "Reload emacs config"))

      ;; (lm/leader-keys
      ;;     "i" '(:ignore t :wk "Insert")
      ;;     "i p" '(org-download-screenshot :wk "Insert screenshot (org)"))

      (lm/leader-keys
          "t" '(:ignore t :wk "Toggle")
          "t n" '(tab-bar-new-tab :wk "New tab")
          "t m" '(tab-bar-mode :wk "Toggle tab bar")
          "t c" '(tab-close :wk "Close tab")
          "t l" '(display-line-numbers-mode :wk "Toggle line numbers")
          "t i" '(org-toggle-inline-images :wk "Toggle inline images")
          "t t" '(visual-line-mode :wk "Toggle truncated lines"))

      (lm/leader-keys
          "s" '(:ignore t :wk "Shell")
          "s c" '(shell-command :wk "Run a shell command")
          "s d" '(sh-cd-here :wk "Move current shell to current dir")
          "s m" '(sh-mode :wk "Shell mode"))

      (lm/leader-keys
          "c" '(:ignore t :wk "Capitalize")
          "c w" '(capitalize-word :wk "Capitalize word")
          "c r" '(capitalize-region :wk "Capitalize region")
          "c c" '(upcase-char :wk "Upcase char")
          "c u" '(upcase-region :wk "Upcase region"))

      (lm/leader-keys
          "l" '(:ignore t :wk "Downcase")
          "l w" '(downcase-word :wk "Downcase word")
          "l u" '(downcase-region :wk "Downcase region"))

      ;; Evil window bindings
      (lm/leader-keys
          "w" '(:ignore t :wk "Window")
          "w w" '(evil-window-next :wk "Next window")
          "w h" '(evil-window-left :wk "Move cursor to window left")
          "w j" '(evil-window-down :wk "Move cursor to window below")
          "w k" '(evil-window-up :wk "Move cursor to window above")
          "w l" '(evil-window-right :wk "Move cursor to window right")
          "w s" '(evil-window-split :wk "Split window horizontally")
          "w v" '(evil-window-vsplit :wk "Split window vertically")
          "w H" '(evil-window-move-far-left :wk "Move split to left")
          "w J" '(evil-window-move-very-bottom :wk "Move split to bottom")
          "w K" '(evil-window-move-very-top :wk "Move split to top")
          "w L" '(evil-window-move-far-right :wk "Move split to right")
          "w >" '(evil-window-increase-width :wk "Increase window width")
          "w ." '(evil-window-increase-width :wk "Increase window width")
          "w <" '(evil-window-decrease-width :wk "Increase window width")
          "w ," '(evil-window-decrease-width :wk "Increase window width")
          "w c" '(evil-window-delete :wk "Close window")
          "w o" '(delete-other-windows :wk "Delete other windows")
          "w =" '(balance-windows :wk "Balance windows")
          "q k" '(kill-buffer-and-window :wk "Kill buf and window")
          "q q" '(save-buffers-kill-terminal :wk "Save bufs, kill term"))

      ;; (evil-global-set-key 'visual "K" (kbd ":m '<-2 RET gv '< gk")) 
      (evil-global-set-key 'visual "K" 'drag-stuff-up) 
      ;; (evil-global-set-key 'visual "J" (kbd ":m '>+1 RET gv '> gj")) 
      (evil-global-set-key 'visual "J" 'drag-stuff-down)

      (lm/leader-keys
         "p" '(:ignore t :wk "Project")
         "p o" '(dashboard-open :wk "Return to dashboard")
         "p f" '(project-find-file :wk "Find project file"))

  )

#+end_src

* ALL THE ICONS
#+begin_src emacs-lisp
  (use-package all-the-icons
      :ensure t
      :diminish
      :if (display-graphic-p))
  (use-package all-the-icons-dired
      :hook (dired-mode . (lambda () (all-the-icons-dired-mode t))))

#+end_src

* AUTOSAVE
#+begin_src emacs-lisp
(setq backup-directory-alist
      `((".*" . "~/emacs/auto-saves")))
(setq auto-save-file-name-transforms
      `((".*" "~/emacs/auto-saves" t)))
#+end_src

* COMPANY
#+begin_src emacs-lisp
  (use-package company
    :defer 2
    :diminish
    :custom
    (company-begin-commands '(self-insert-command))
    (company-idle-delay .1)
    (company-minimum-prefix-length 2)
    (company-show-numbers t)
    (company-tooltip-align-annotations 't)
    (global-company-mode t))

  (use-package company-box
    :after company
    :diminish
    :hook (company-mode . company-box-mode))
#+end_src

* DASHBOARD

#+begin_src emacs-lisp
    (use-package dashboard
        :ensure t
        :diminish
        :init
        (setq initial-buffer-choice 'dashboard-open)
        (setq dashboard-set-heading-icons t)
        ;; (setq dashboard-set-navigator t)
        (setq dashboard-set-file-icons t)
        (setq dashboard-banner-logo-title "Welcome to Emacs!")
        (setq dashboard-startup-banner 'logo) ;; default logo
        (setq dashboard-center-content t)
        (setq dashboard-items '((recents . 5)
                                (agenda . 5)
                                (bookmarks . 3)
                                (projects . 3)))
        :config
        (dashboard-setup-startup-hook))

#+end_src

* DIMINISH
This package implements hiding or abbreviation of the modeline displays (lighters) of minor-modes.  With this package installed, you can add ':diminish' to any use-package block to hide that particular mode in the modeline.

#+begin_src emacs-lisp
(use-package diminish)

#+end_src

* DRAG-STUFF
#+begin_src emacs-lisp
  (use-package drag-stuff
      :diminish
      :config
  (drag-stuff-global-mode 1))

#+end_src

* FLYCHECK
Install =luacheck= from your Linux distro's repositories for flycheck to work correctly with lua files.  Install =python-pylint= for flycheck to work with python files.  Haskell works with flycheck as long as =haskell-ghc= or =haskell-stack-ghc= is installed.  For more information on language support for flycheck, [[https://www.flycheck.org/en/latest/languages.html][read this]].

#+begin_src emacs-lisp
(use-package flycheck
  :ensure t
  :defer t
  :diminish
  :init (global-flycheck-mode))
#+end_src

* FONTS
Defining the various fonts emacs will use

** Setting The Font Face

#+begin_src emacs-lisp
(set-face-attribute 'default nil
  :font "MPLUSCodeLatin60"
  :height 110
  :weight 'medium)
(set-face-attribute 'variable-pitch nil
  :font "MPLUSCodeLatin60"
  :height 120
  :weight 'medium)
(set-face-attribute 'fixed-pitch nil
  :font "MPLUSCodeLatin60"
  :height 130
  :weight 'medium)

;; Makes commented text and keywords italics.
;; This is working in emacsclient but not emacs.
;; Your font must have an italic face available.
(set-face-attribute 'font-lock-comment-face nil
  :slant 'italic)
(set-face-attribute 'font-lock-keyword-face nil
  :slant 'italic)
;; This sets the default font on all graphical frames created after restarting Emacs.
;; Does the same thing as 'set-face-attribute default' above, but emacsclient fonts
;; are not right unless I also add this method of setting the default font.
(add-to-list 'default-frame-alist '(font . "MPLUSCodeLatin60-12"))

;; uncomment the following line if line spacing needs adjusting.
;; (setq-default line-spacing 0.12)

#+end_src

** Zoom In/Out
Enable zoom in/out with c-=/- and also for c-scrl-up/down
#+begin_src emacs-lisp
(global-set-key (kbd "C-=") 'text-scale-increase) 
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "<C-wheel-up>") 'text-scale-increase)
(global-set-key (kbd "<c-wheel-down>") 'text-scale-decrease)
#+end_src

* GNUPLOT
#+begin_src emacs-lisp
  (use-package gnuplot-mode)
  ;; automatically open files ending with .gp or .gnuplot in gnuplot mode
  ;; (setq auto-mode-alist 
  ;; (append '(("\\.\\(gp\\|gnuplot\\)$" . gnuplot-mode)) auto-mode-alist)))

#+end_src

* IMAGE DIR-ED
#+begin_src emacs-lisp
  (use-package image-dired+)
#+end_src

* INDENTING/TABS
#+begin_src emacs-lisp
  (setq-default indent-tabs-mode nil)
  (setq-default tab-width 2)
  (setq-default indent-line-function 'insert-tab)
  (setq-default c-basic-offset 2)
 ;; if indent-tabs-mode is off, untabify before saving
 ;;(add-hook 'write-file-hooks 
 ;;         (lambda () (if (not indent-tabs-mode)
 ;;                        (untabify (point-min) (point-max)))))
#+end_src

* LIGATURES
#+begin_src emacs-lisp
;; this assumes you've installed the package via melpa.
(use-package ligature
  :config
  ;; enable the "www" ligature in every possible major mode
  (ligature-set-ligatures 't '("www"))
  ;; enable traditional ligature support in eww-mode, if the
  ;; `variable-pitch' face supports it
  (ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi"))
  ;; enable all cascadia code ligatures in programming modes
  (ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
                                       ":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
                                       "!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
                                       "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
                                       "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
                                       "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
                                       "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
                                       "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
                                       ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
                                       "<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
                                       "##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
                                       "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
                                       "\\\\" "://"))
  ;; enables ligature checks globally in all buffers. you can also do it
  ;; per mode with `ligature-mode'.
  (global-ligature-mode t))
#+end_src

* MARKDOWN MODE
#+begin_src emacs-lisp
(use-package markdown-mode
  :ensure t
  :mode ("readme\\.md\\'" . gfm-mode)
  :init (setq markdown-command "multimarkdown"))

#+end_src

* ORG DOWNLOAD
#+begin_src emacs-lisp
(use-package org-download
  :after org
  :defer nil
  :custom
  (org-download-method 'directory)
  (org-download-image-dir "~/emacs/images/")
  (org-download-heading-lvl 0)
  (org-download-timestamp "org_%y%m%d-%h%m%s_")
  (org-image-actual-width 400)
  (org-download-screenshot-method "wayland_display=wayland-1 wl-paste -t image/png > '%s'.png")
  :bind
  ("C-M-y" . org-download-screenshot)
  :config
  (require 'org-download))
#+end_src

* PULSE
Pulse highlight a line on certain actions

#+begin_src emacs-lisp
  (use-package pulse
    :ensure nil
    :defer nil
    :init
    (defun pulse-line (&rest _)
      "pulse the current line"
      (pulse-momentary-highlight-one-line (point)))

    (dolist (command '(scroll-up-command
                       scroll-down-command
                       windmove-left
                       windmove-right
                       windmove-up
                       windmove-down
                       move-to-window-line-top-bottom
                       other-window
                       recenter-top-bottom
                       evil-scroll-up
                       evil-scroll-down
                       evil-scroll-page-up
                       evil-scroll-page-down
                       ))
    (advice-add command :after #'pulse-line))

    (setq pulse-flag t)
    (global-set-key (kbd "M-p") (lambda ()
                              (interactive)
                              (pulse-line))))   ;; (global-set-key (kbd "M-p") 'pulse-line) 
#+end_src

* PDF TOOLS
#+begin_src emacs-lisp
  (use-package pdf-tools
     :defer t
     :config
         (pdf-tools-install)
         (setq-default pdf-view-display-size 'fit-page)
     :bind (:map pdf-view-mode
           ("\\" . hydra-pdftools/body)
           ("<s-spc>" .  pdf-view-scroll-down-or-next-page)
           ("g"  . pdf-view-first-page)
           ("G"  . pdf-view-last-page)
           ("l"  . image-forward-hscroll)
           ("h"  . image-backward-hscroll)
           ("j"  . pdf-view-next-page)
           ("k"  . pdf-view-previous-page)
           ("e"  . pdf-view-goto-page)
           ("u"  . pdf-view-revert-buffer)
           ("al" . pdf-annot-list-annotations)
           ("ad" . pdf-annot-delete)
           ("aa" . pdf-annot-attachment-dired)
           ("am" . pdf-annot-add-markup-annotation)
           ("at" . pdf-annot-add-text-annotation)
           ("y"  . pdf-view-kill-ring-save)
           ("i"  . pdf-misc-display-metadata)
           ("s"  . pdf-occur)
           ("b"  . pdf-view-set-slice-from-bounding-box)
           ("r"  . pdf-view-reset-slice)))

     (use-package org-pdfview
         :config 
                 (add-to-list 'org-file-apps
                 '("\\.pdf\\'" . (lambda (file link)
                 (org-pdfview-open link)))))

  (with-eval-after-load 'pdf-view
    (define-key pdf-view-mode-map (kbd "j") #'pdf-view-next-page)
    (define-key pdf-view-mode-map (kbd "k") #'pdf-view-previous-page)
    (define-key pdf-view-mode-map (kbd "C-j") #'pdf-view-next-line-or-next-page)
    (define-key pdf-view-mode-map (kbd "C-k") #'pdf-view-previous-line-or-previous-page))
#+end_src


* PROJECTILE
[[HTTPS://GITHUB.COM/BBATSOV/PROJECTILE][Projectile]] is a project interaction library for emacs.

#+begin_src emacs-lisp
  (use-package projectile
    :diminish
    :config
    (projectile-mode 1))
#+end_src

* RAINBOW MODE
Display the actual color as a background for any hex color value (ex. #ffffff).  The code block below enables rainbow-mode in all programming modes (prog-mode) as well as org-mode, which is why rainbow works in this document.  

#+begin_src emacs-lisp
  (use-package rainbow-mode
    :diminish
    :hook 
    ((org-mode prog-mode) . rainbow-mode))
#+end_src

* RELOAD EMACS
This is just an example of how to create a simple function in emacs. Use this function to reload emacs after adding changes to the config. Yes, i am loading the user-init-file twice in this function, which is a hack because for some reason, just loading the user-init-file once does not work properly.

#+begin_src emacs-lisp
  (defun reload-init-file ()
    (interactive)
    (load-file user-init-file)
    (load-file user-init-file))
#+end_src

* SHELLS AND TERMINALS

** ESHELL

#+begin_src emacs-lisp
  (use-package eshell-syntax-highlighting
      :after esh-mode
      :config
      (eshell-syntax-highlighting-global-mode +1))

      (setq eshell-rc-script (concat user-emacs-directory "eshell/profile")
        eshell-aliases-file (concat user-emacs-directory "eshell/aliases")
        eshell-history-size 5000
        eshell-buffer-maximum-lines 5000
        eshell-hist-ignoredups t
        eshell-scroll-to-bottom-on-input t
        eshell-destroy-buffer-when-process-dies t
        eshell-visual-commands'("bash" "fish" "htop" "ssh" "top" "zsh"))
#+end_src

* SUDO EDIT
Enable editing of privileged files

#+begin_src emacs-lisp
(use-package sudo-edit
    :config
      (lm/leader-keys
          "fu" '(sudo-edit-find-file :wk "sudo find file")
          "fu" '(sudo-edit :wk "sudo edit file"))) 

#+end_src

* THEME
Set themes dir, load chosen theme - theme made with [[https://emacsfodder.github.io/emacs-theme-editor/][emacs theme editor]].
#+begin_src emacs-lisp
  ;;(add-to-list 'custom-theme-load-path "~/.config/emacs/themes")
  ;;(load-theme 'soft-charcoal t)

  (use-package doom-themes
  :ensure t
  :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-monokai-spectrum t)
    ;; (load-theme 'doom-monokai-machine t)

  ;; enable flashing mode-line on errors
  (doom-themes-visual-bell-config)
  ;; enable custom neotree theme (all-the-icons must be installed!)
  (doom-themes-neotree-config)
  ;; or for treemacs users
  (setq doom-themes-treemacs-theme "doom-colors") ; 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
True transparency support as of emacs 29
#+begin_src emacs-lisp
  (add-to-list 'default-frame-alist '(alpha-background . 100)) ;; for all new frames
#+end_src


* GUI TWEAKS
Making the ui look nicer

** Disable menubar, toolbars and scrollbars

#+begin_src emacs-lisp
  (menu-bar-mode -1)
  (tool-bar-mode -1)
  (scroll-bar-mode -1)
#+end_src

** Display line numbers and truncated lines

#+begin_src emacs-lisp
  (global-display-line-numbers-mode 0)
  (menu-bar--display-line-numbers-mode-relative)
  ;; (setq display-line-numbers-mode-relative 't)

  (global-visual-line-mode t)
  (column-number-mode)
#+end_src

* IVY (COUNSEL)
+ Ivy, a generic completion mechanism for emacs.
+ Counsel, a collection of ivy-enhanced versions of common emacs commandS.
+ Ivy-rich allows us to add descriptions alongside the commands in m-x.

#+begin_src emacs-lisp
  (use-package counsel
    :after ivy
    :diminish
    :config (counsel-mode))

  (use-package ivy
    :bind
    ;; ivy-resume resumes the last ivy-based completion.
    (("C-c C-r" . ivy-resume)
     ("C-x b" . ivy-switch-buffer-other-window))
    :diminish
    :custom
    (setq ivy-use-virtual-buffers t)
    (setq ivy-count-format "(%d/%d) ")
    (setq enable-recursive-minibuffers t)
    :config
    (ivy-mode))

  (use-package all-the-icons-ivy-rich
    :ensure t
    :diminish
    :init (all-the-icons-ivy-rich-mode 1))

  (use-package ivy-rich
    :after ivy
    :diminish
    :ensure t
    :init (ivy-rich-mode 1) ;; this gets us descriptions in m-x.
    :custom
    (ivy-virtual-abbreviate 'full
     ivy-rich-switch-buffer-align-virtual-buffer t
     ivy-rich-path-style 'abbrev)
    :config
    (ivy-set-display-transformer 'ivy-switch-buffer
                                 'ivy-rich-switch-buffer-transformer))
  (with-eval-after-load 'ivy
    (define-key ivy-minibuffer-map (kbd "C-k") #'ivy-previous-line)
    (define-key ivy-minibuffer-map (kbd "C-j") #'ivy-next-line))
#+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.

#+begin_src emacs-lisp
  (use-package zig-mode)
  (use-package nix-mode)
  ;; (use-package jai-mode)
  (use-package rust-mode)
  (use-package cargo-mode)
  (use-package lua-mode)
  (add-to-list 'load-path "~/.config/emacs/manual-packages")
  (require 'odin-mode)
#+end_src


* ORG MODE
** Enabling table of contents

#+begin_src emacs-lisp
  (use-package toc-org
      :commands toc-org-enable
      :init (add-hook 'org-mode-hook 'toc-org-enable))
#+end_src

** Enabling org bullets
Org-bullets give bullet points instead of asterisks

#+begin_src emacs-lisp
  (add-hook 'org-mode-hook 'org-indent-mode)
  ;;(setq (setq org-return-follows-link  t)
  (use-package org-bullets)
  (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
#+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
** Pdf links
#+begin_src emacs-lisp
;; (eval-after-load 'org '(require 'org-pdfview))
;; 
;; (add-to-list 'org-file-apps 
;;              '("\\.pdf\\'" . (lambda (file link)
;;                                      (org-pdfview-open link))))
#+end_src emacs-lisp

* WHICH-KEY

#+begin_src emacs-lisp
  (use-package which-key
    :init
        (which-key-mode 1)
    :diminish
    :config
    (setq which-key-side-window-location 'bottom
          which-key-sort-order #'which-key-key-order-alpha
          which-key-sort-uppercase-first nil
          which-key-add-column-padding 1
          which-key-max-display-columns nil
          which-key-min-display-lines 6
          which-key-side-window-slot -10
          which-key-side-window-max-height 0.25
          which-key-ide-delay 0.8
          which-key-max-description-length 25
          which-key-allow-imprecise-window-fit nil
          which-key-separator " -> " ))
#+end_src
