374 lines
11 KiB
Org Mode

#+TITLE: Emacs Config
#+AUTHOR: Joseph Ferano
#+PROPERTY: header-args:emacs-lisp :tangle ./init.el
#+STARTUP: overview
#+TOC: true
** Early Init
*** Garbage Collection
The default Garbage Collector is triggered at 800 KB, way too conservative, let's bump to 512 MB.
Garbage collection is a big contributor to startup times. This fends it off, then is reset later by
enabling `gcmh-mode'. Not resetting it will cause stuttering/freezes.
#+begin_src emacs-lisp :tangle ./early-init.el
;; -*- lexical-binding: t; -*-
(defvar default-file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
(setq gc-cons-threshold (expt 2 32))
(add-hook 'emacs-startup-hook
(lambda ()
"Restore defalut values after init."
(setq file-name-handler-alist default-file-name-handler-alist)
(if (boundp 'after-focus-change-function)
(add-function :after after-focus-change-function
(lambda ()
(unless (frame-focus-state)
(garbage-collect))))
(add-hook 'focus-out-hook 'garbage-collect))))
(setq native-comp-deferred-compilation nil)
#+end_src
#+begin_src emacs-lisp :tangle ./early-init.el
(setq max-specpdl-size 1200)
(setq max-lisp-eval-depth 800)
(add-hook 'window-setup-hook
(lambda ()
(setq-default inhibit-redisplay nil
inhibit-message nil)
(redisplay)))
#+end_src
*** Setup
Disable package.el, since we will be using straight.el. According to the straight.el
documentation;
#+BEGIN_QUOTE
While it is technically possible to use both package.el and straight.el at the same time, there is no real reason to, and it might result in oddities like packages getting loaded more than once.
#+END_QUOTE
Either way, if you need to quickly install a package for testing, you can just run
=(straight-use-package)= interactively.
#+BEGIN_SRC emacs-lisp :tangle ./early-init.el
(setq package-enable-at-startup nil)
#+END_SRC
*** Enhancements
Prioritize old byte-compiled source files over newer sources. It saves us a little IO time to skip all the mtime checks on each lookup.
#+begin_src emacs-lisp :tangle ./early-init.el
(setq load-prefer-newer nil)
#+end_src
#+begin_src emacs-lisp :tangle ./early-init.el
(set-language-environment "UTF-8")
(setq default-input-method nil)
;;; early-init.el ends here
#+end_src
** Straight.el
For now, use [[https://github.com/radian-software/straight.el][straight.el]] until [[https://github.com/progfolio/elpaca
][elpaca]] is ready for production use.
Then bootstrap
#+BEGIN_SRC emacs-lisp
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
#+END_SRC
** Misc Stuff
#+begin_SRC emacs-lisp
;; (straight-use-package 'benchmark-init)
;; (require 'benchmark-init)
;; (add-hook 'after-init-hook 'benchmark-init/deactivate)
(setq vc-follow-symlinks t) ; Visit real file when editing a symlink without prompting.
(global-auto-revert-mode t) ; Revert buffer's file when the file changes on disk
(setq confirm-kill-emacs 'y-or-n-p)
(setq use-dialog-box nil)
(fset 'yes-or-no-p 'y-or-n-p)
(setq large-file-warning-threshold 100000000)
(setq backup-directory-alist `((".*" . ,(expand-file-name "backups" user-emacs-directory))))
(setq backup-by-copying t
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
#+END_SRC
** Visuals
Use Dashboard.el. First load `all-the-icons` for nicer rendering
#+begin_src emacs-lisp
(straight-use-package 'all-the-icons)
(straight-use-package 'dashboard)
(dashboard-setup-startup-hook)
(setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")))
(setq dashboard-startup-banner 'logo)
(setq dashboard-center-content t)
(setq dashboard-set-file-icons t)
(setq dashboard-set-heading-icons t)
(add-hook 'dashboard-mode-hook (lambda () (setq-local line-spacing 12)))
#+end_src
Setup other stuff
#+begin_src emacs-lisp
(add-hook 'text-mode-hook (lambda () (setq fill-column 100) (turn-on-auto-fill)))
(setq-default display-line-numbers 'relative)
(make-variable-buffer-local 'global-hl-line-mode)
(dolist (mode '( dashboard-mode-hook org-mode-hook term-mode-hook eww-mode-hook vterm-mode-hook
eshell-mode-hook dired-mode-hook shell-mode-hook magit-mode-hook))
(add-hook mode (lambda () (display-line-numbers-mode 0))))
(set-window-margins nil 0)
(setq-default right-fringe-width 10)
(setq scroll-margin 0
scroll-conservatively 100000
scroll-preserve-screen-position 1)
(global-hl-line-mode +1)
(column-number-mode +1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(menu-bar-mode -1)
(tooltip-mode -1)
(modify-all-frames-parameters
'((right-divider-width . 5)
(internal-border-width . 10)))
(setq inhibit-startup-screen t)
(straight-use-package 'doom-themes)
(setq custom-safe-themes t)
(load-theme 'doom-vibrant t)
;; (load-theme 'doom-flatwhite t)
(straight-use-package 'ligature)
(global-ligature-mode)
(straight-use-package 'highlight-quoted)
(add-hook 'emacs-lisp-mode-hook 'highlight-quoted-mode)
(straight-use-package 'nano-modeline)
(nano-modeline-mode)
#+end_src
** Text
#+begin_src emacs-lisp
(set-face-attribute 'default nil :font "Fira Code Nerd Font" :height 105)
(setq-default c-basic-offset 4) ;; This is annoying
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq-default line-spacing 5)
(setq indent-line-function 'insert-tab)
(set-default 'truncate-lines nil)
(set-default 'truncate-partial-width-windows nil)
(add-hook 'before-save-hook 'whitespace-cleanup)
#+end_src
** Org Mode
#+begin_src emacs-lisp
(require 'org)
(setq org-todo-keywords '((sequence "TODO" "IN-PROGRESS" "|" "DONE" "BACKLOG")))
(setq org-agenda-files '("~/todo.org"))
(straight-use-package 'org-bullets)
(defun joe/org-hook () (org-bullets-mode) (org-indent-mode))
(add-hook 'org-mode-hook 'joe/org-hook)
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(setq org-edit-src-content-indentation 0)
#+end_src
** VEMCO (Vertico Embark Marginalia Consult Orderless)
#+begin_src emacs-lisp
(straight-use-package '(vertico :files (:defaults "extensions/*") :includes (vertico-directory)))
;; :bind (:map vertico-map
;; ("\M-G" . vertico-multiform-mode)
;; ("\M-e" . embark-act)))
(vertico-mode)
(require 'savehist)
(savehist-mode)
(straight-use-package 'vertico-directory)
;; :bind (:map vertico-map
;; ("RET" . vertico-directory-enter)
;; ("DEL" . vertico-directory-delete-char)
;; ("M-DEL" . vertico-directory-delete-word))
;; :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))
(straight-use-package 'embark)
(straight-use-package 'embark-consult)
(straight-use-package 'marginalia)
(marginalia-mode)
(setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
(straight-use-package 'consult)
(straight-use-package 'orderless)
(setq completion-styles '(orderless basic)
completion-category-overrides '((file (styles basic partial-completion))))
#+end_src
** Dirvish/Dired
#+begin_src emacs-lisp
(straight-use-package 'dirvish)
(dirvish-override-dired-mode)
(setq delete-by-moving-to-trash t)
(setq dired-dwim-target t)
(dirvish-define-preview exa (file)
"Use `exa' to generate directory preview."
:require ("exa") ; tell Dirvish to check if we have the executable
(when (file-directory-p file) ; we only interest in directories here
`(shell . ("exa" "--color=always" "-al" ,file)))) ; use the command output as preview
(add-to-list 'dirvish-preview-dispatchers 'exa)
(setq dired-listing-switches "-l --almost-all --human-readable --time-style=long-iso --group-directories-first --no-group")
(setq dirvish-preview-dispatchers (cl-substitute 'pdf-preface 'pdf dirvish-preview-dispatchers))
#+end_src
** Terminals/Shells
#+begin_src emacs-lisp
(straight-use-package 'vterm)
(setq vterm-shell "/bin/fish")
(setq vterm-timer-delay 0.01)
(setq vterm-buffer-name-string "VTerm - %s")
(setq vterm-max-scrollback 100000)
#+end_src
** Undo Tree
#+begin_src emacs-lisp
(straight-use-package 'undo-tree)
(require 'undo-tree)
(global-undo-tree-mode)
(setq undo-tree-visualizer-diff t)
(setq undo-tree-history-directory-alist `(("." . ,(expand-file-name "undo" user-emacs-directory))))
#+end_src
** Text Editor
#+begin_src emacs-lisp
(straight-use-package 'meow)
(require 'meow)
(defun meow-setup ()
(setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
(meow-motion-overwrite-define-key
'("j" . meow-next)
'("k" . meow-prev)
'("<escape>" . ignore))
(meow-leader-define-key
;; SPC j/k will run the original command in MOTION state.
'("j" . "H-j")
'("k" . "H-k")
;; Use SPC (0-9) for digit arguments.
'("1" . meow-digit-argument)
'("2" . meow-digit-argument)
'("3" . meow-digit-argument)
'("4" . meow-digit-argument)
'("5" . meow-digit-argument)
'("6" . meow-digit-argument)
'("7" . meow-digit-argument)
'("8" . meow-digit-argument)
'("9" . meow-digit-argument)
'("0" . meow-digit-argument)
'("/" . meow-keypad-describe-key)
'("?" . meow-cheatsheet))
(meow-normal-define-key
'("0" . meow-expand-0)
'("9" . meow-expand-9)
'("8" . meow-expand-8)
'("7" . meow-expand-7)
'("6" . meow-expand-6)
'("5" . meow-expand-5)
'("4" . meow-expand-4)
'("3" . meow-expand-3)
'("2" . meow-expand-2)
'("1" . meow-expand-1)
'("-" . negative-argument)
'(";" . meow-reverse)
'("," . meow-inner-of-thing)
'("." . meow-bounds-of-thing)
'("[" . meow-beginning-of-thing)
'("]" . meow-end-of-thing)
'("a" . meow-append)
'("A" . meow-open-below)
'("b" . meow-back-word)
'("B" . meow-back-symbol)
'("c" . meow-change)
'("d" . meow-delete)
'("D" . meow-backward-delete)
'("e" . meow-next-word)
'("E" . meow-next-symbol)
'("f" . meow-find)
'("g" . meow-cancel-selection)
'("G" . meow-grab)
'("h" . meow-left)
'("H" . meow-left-expand)
'("i" . meow-insert)
'("I" . meow-open-above)
'("j" . meow-next)
'("J" . meow-next-expand)
'("k" . meow-prev)
'("K" . meow-prev-expand)
'("l" . meow-right)
'("L" . meow-right-expand)
'("m" . meow-join)
'("n" . meow-search)
'("o" . meow-block)
'("O" . meow-to-block)
'("p" . meow-yank)
'("q" . meow-quit)
'("Q" . meow-goto-line)
'("r" . meow-replace)
'("R" . meow-swap-grab)
'("s" . meow-kill)
'("t" . meow-till)
'("u" . meow-undo)
'("U" . meow-undo-in-selection)
'("v" . meow-visit)
'("w" . meow-mark-word)
'("W" . meow-mark-symbol)
'("x" . meow-line)
'("X" . meow-goto-line)
'("y" . meow-save)
'("Y" . meow-sync-grab)
'("z" . meow-pop-selection)
'("'" . repeat)
'("<escape>" . ignore)))
(meow-setup)
;; (meow-global-mode t)
#+end_src
** Magit
#+begin_src emacs-lisp
(straight-use-package 'magit)
#+end_src
* COMMENT Local variables
;; Local Variables:
;; eval: (add-hook 'after-save-hook '(lambda () (org-babel-tangle)) nil t)
;; End: