diff --git a/Emacs/.config/emacs/config.org b/Emacs/.config/emacs/config.org
index 4ddeee4..229aaa7 100644
--- a/Emacs/.config/emacs/config.org
+++ b/Emacs/.config/emacs/config.org
@@ -239,795 +239,6 @@ the borders for Emacs.
:config
(fringe-mode 0))
#+end_src
-* Core packages
-
-** General
-A good package for defining key bindings. In this case, I generate a
-new definer for the "LEADER" keys. Leader is bound to ~SPC~ and it's
-functionally equivalent to the doom/spacemacs leader. Local leader is
-bound to ~SPC ,~ and it's similar to doom/spacemacs leader but doesn't
-try to fully assimilate the local-leader map, instead just picking
-stuff I think is useful. I also create defines for general root
-bindings.
-#+begin_src emacs-lisp
-(use-package general
- :demand t
- :config
- ;; General which key definitions for leaders
- (general-def
- :states '(normal motion)
- "SPC" nil
- "SPC ," '(nil :which-key "Local leader")
- "SPC c" '(nil :which-key "Code")
- "SPC f" '(nil :which-key "File")
- "SPC t" '(nil :which-key "Shell")
- "SPC m" '(nil :which-key "Toggle modes")
- "SPC a" '(nil :which-key "Applications")
- "SPC s" '(nil :which-key "Search")
- "SPC b" '(nil :which-key "Buffers")
- "SPC q" '(nil :which-key "Quit/Literate")
- "SPC i" '(nil :which-key "Insert")
- "SPC d" '(nil :which-key "Directories"))
-
- (general-create-definer leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC")
-
- (general-create-definer local-leader
- :states '(normal motion)
- :prefix "SPC ,")
-
- (general-create-definer code-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC c")
-
- (general-create-definer file-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC f")
-
- (general-create-definer shell-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC t")
-
- (general-create-definer mode-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC m")
-
- (general-create-definer app-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC a")
-
- (general-create-definer search-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC s")
-
- (general-create-definer buffer-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC b")
-
- (general-create-definer quit-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC q")
-
- (general-create-definer insert-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC i")
-
- (general-create-definer dir-leader
- :states '(normal motion)
- :keymaps 'override
- :prefix "SPC d")
-
- (general-create-definer general-nmmap
- :states '(normal motion))
-
- (defalias 'nmmap #'general-nmmap)
-
- (general-evil-setup t))
-#+end_src
-
-*** Some default binds in Emacs
-Bindings for core functionality
-#+begin_src emacs-lisp
-(use-package emacs
- :straight nil
- :general
- (general-def
- "C-x d" #'delete-frame)
-
- (nmmap
- "C--" #'text-scale-decrease
- "C-=" #'text-scale-increase)
-
- (leader
- "SPC" '(execute-extended-command :which-key "M-x")
- "'" '(browse-url-emacs :which-key "Open url in Emacs")
- "u" 'universal-argument
- ";" 'eval-expression
- ":" `(,(proc (interactive) (switch-to-buffer "*scratch*"))
- :which-key "Switch to *scratch*")
- "!" '(async-shell-command :which-key "Async shell command")
- "h" '(help-command :which-key "Help"))
-
- (code-leader
- "j" #'next-error
- "k" #'previous-error
- "c" #'compile
- "C" #'recompile
- "F" (list (proc (interactive) (find-file "~/Code/")) ':which-key "Open ~/Code/"))
-
- (file-leader
- "f" #'find-file
- "F" #'find-file-other-frame
- "s" #'save-buffer
- "p" (list (proc (interactive) (find-file (concat user-emacs-directory "config.org")))
- ':which-key "Open config.org"))
-
- (quit-leader
- "q" #'save-buffers-kill-terminal
- "c" #'+literate/compile-config
- "l" #'+literate/load-config
- "d" #'delete-frame)
-
- (search-leader "i" #'imenu))
-#+end_src
-** Evil
-Evil (Emacs VI Layer) is a package that brings the Vi experience to
-Emacs. Packaged with it by default are:
-- The modal system
-- EX
-- Vi mapping functions
-
-This provides a lot of stuff for the average vim user moving to Emacs.
-However there are many other packages surrounding evil that port even
-greater functionality from vim to Emacs. Surround, commenting,
-multiple cursors and further support to other packages are configured
-here.
-*** Evil core
-Setup the evil package, with some opinionated keybindings:
-
-- Switch ~evil-upcase~ and ~evil-downcase~ because I use ~evil-upcase~
- more
-- Switch ~evil-goto-mark~ and ~evil-goto-mark-line~ as I'd rather have
- the global one closer to the home row
-- Use 'T' character as an action for transposing objects
-#+begin_src emacs-lisp
-(use-package evil
- :demand t
- :hook (after-init-hook . evil-mode)
- :general
- (leader
- "w" '(evil-window-map :which-key "Window")
- "wd" #'delete-frame)
-
- (nmmap
- "TAB" #'evil-jump-item
- "r" #'evil-replace-state
- "zC" #'hs-hide-level
- "'" #'evil-goto-mark
- "`" #'evil-goto-mark-line
- "C-w" #'evil-window-map
- "gu" #'evil-upcase
- "gU" #'evil-downcase
- "T" nil)
-
- (nmmap
- :infix "T"
- "w" #'transpose-words
- "c" #'transpose-chars
- "s" #'transpose-sentences
- "p" #'transpose-paragraphs
- "e" #'transpose-sexps
- "l" #'transpose-lines)
- :init
- (setq evil-want-keybinding nil
- evil-split-window-below t
- evil-vsplit-window-right t
- evil-want-abbrev-expand-on-insert-exit t
- evil-undo-system #'undo-tree)
- :config
- (fset #'evil-window-vsplit #'make-frame))
-#+end_src
-*** Evil surround
-#+begin_src emacs-lisp
-(use-package evil-surround
- :after evil
- :config
- (global-evil-surround-mode))
-#+end_src
-*** Evil commentary
-#+begin_src emacs-lisp
-(use-package evil-commentary
- :after evil
- :config
- (evil-commentary-mode))
-#+end_src
-*** Evil multi cursor
-Setup for multi cursors in Evil mode. Don't let evil-mc setup it's own
-keymap because it uses 'gr' as its prefix, which I don't like.
-#+begin_src emacs-lisp
-(use-package evil-mc
- :after evil
- :init
- (defvar evil-mc-key-map (make-sparse-keymap))
- :general
- (nmap
- :infix "gz"
- "q" #'evil-mc-undo-all-cursors
- "d" #'evil-mc-make-and-goto-next-match
- "j" #'evil-mc-make-cursor-move-next-line
- "k" #'evil-mc-make-cursor-move-prev-line
- "j" #'evil-mc-make-cursor-move-next-line
- "m" #'evil-mc-make-all-cursors
- "z" #'evil-mc-make-cursor-here
- "r" #'evil-mc-resume-cursors
- "s" #'evil-mc-pause-cursors
- "u" #'evil-mc-undo-last-added-cursor)
- :config
- ;; (evil-mc-define-vars)
- ;; (evil-mc-initialize-vars)
- ;; (add-hook 'evil-mc-before-cursors-created #'evil-mc-pause-incompatible-modes)
- ;; (add-hook 'evil-mc-before-cursors-created #'evil-mc-initialize-active-state)
- ;; (add-hook 'evil-mc-after-cursors-deleted #'evil-mc-teardown-active-state)
- ;; (add-hook 'evil-mc-after-cursors-deleted #'evil-mc-resume-incompatible-modes)
- ;; (advice-add #'evil-mc-initialize-hooks :override #'ignore)
- ;; (advice-add #'evil-mc-teardown-hooks :override #'evil-mc-initialize-vars)
- ;; (advice-add #'evil-mc-initialize-active-state :before #'turn-on-evil-mc-mode)
- ;; (advice-add #'evil-mc-teardown-active-state :after #'turn-off-evil-mc-mode)
- ;; (add-hook 'evil-insert-state-entry-hook #'evil-mc-resume-cursors)
- (global-evil-mc-mode))
-#+end_src
-
-*** Evil collection
-Setup evil collection, but don't turn on the mode. Instead, I'll turn
-on setups for specific modes I think benefit from it.
-#+begin_src emacs-lisp
-(use-package evil-collection
- :after evil)
-#+end_src
-** Completion
-Emacs is a text based interface. Though the standard model of
-completion may be desirable to some it can be modernised through the
-use of 'completion frameworks'.
-
-These frameworks handle input and present output from the user for
-common commands, providing a differing interface to the one Emacs
-comes with. Most of these completion frameworks provide a text based
-menu that is actively filtered as more input is provided (progressive
-input filtering). Along with these frameworks come added
-functionality and applications to integrate into the Emacs environment
-further.
-
-One may say that when using a completion framework there is no point
-in using any other framework as they encompasses so much of the
-default functionality. This is wrong: I'd argue that with a bit of
-management and Emacs lisp it's totally possible to pick and mix your
-options. For small number selections (like finding files) use
-something like Ido and for something larger like searching buffers use
-ivy.
-
-Along with frameworks, there is a configuration for the
-completions-list, which is actually the original and default method of
-completion within Emacs. When you first install Emacs without a
-config, any 'completing-read' function leverages the completions-list when
-~TAB~ is used.
-
-Though I believe Ido is a better completion system than the
-completions-list, it still has it's place and can be used in tandem
-with ido.
-*** Amx
-Amx is a fork of Smex that works to enhance the
-execute-extended-command interface. It also provides support for ido
-or ivy (though I'm likely to use ido here) and allows you to switch
-between them.
-
-It provides a lot of niceties such as presenting the key bind when
-looking for a command.
-
-#+begin_src emacs-lisp
-(use-package amx
- :config
- (amx-mode))
-#+end_src
-*** Orderless
-Orderless sorting method for completion, probably one of the best
-things ever.
-#+begin_src emacs-lisp
-(use-package orderless
- :after (ivy ido)
- :config
- (setf (alist-get t ivy-re-builders-alist) 'orderless-ivy-re-builder))
-#+end_src
-*** Ido
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no
-:END:
-Ido is a very old completion package that still works great to this
-day. Though it is limited in its scope (and may thus be called a
-completion add-on rather than a full on framework), it is still a very
-powerful package. With the use of ido-completing-read+, it may be used
-similarly to a fully fledged completion framework.
-
-#+begin_src emacs-lisp
-(use-package ido
- :demand t
- :general
- (general-def
- :keymaps '(ido-buffer-completion-map
- ido-file-completion-map
- ido-file-dir-completion-map
- ido-common-completion-map)
- (kbd "M-j") #'ido-next-match
- (kbd "M-k") #'ido-prev-match
- (kbd "C-x o") #'evil-window-up)
- :init
- (setq ido-decorations
- (list "{" "}" " \n" " ..." "[" "]" " [No match]" " [Matched]"
- " [Not readable]" " [Too big]" " [Confirm]")
- completion-styles '(flex partial-completion intials emacs22))
- (setq-default ido-enable-flex-matching t
- ido-enable-dot-prefix t
- ido-enable-regexp nil)
- (with-eval-after-load "magit"
- (setq magit-completing-read-function 'magit-ido-completing-read))
- :config
- (ido-mode)
- (ido-everywhere))
-#+end_src
-**** Ido ubiquitous
-Ido completing-read+ is a package that extends the ido package to work
-with more text based functions.
-#+begin_src emacs-lisp
-(use-package ido-completing-read+
- :after ido
- :config
- (ido-ubiquitous-mode +1))
-#+end_src
-*** Completions-list
-#+begin_src emacs-lisp
-(use-package simple
- :straight nil
- :general
- (nmmap
- :keymaps 'completion-list-mode-map
- "l" #'next-completion
- "h" #'previous-completion
- "ESC" #'delete-completion-window
- "q" #'quit-window
- "RET" #'choose-completion)
- :config
- (with-eval-after-load "evil"
- (setq evil-emacs-state-modes (cl-remove-if
- #'(lambda (x) (eq 'completions-list-mode x))
- evil-emacs-state-modes))
- (add-to-list 'evil-normal-state-modes 'completions-list-mode)))
-#+end_src
-*** Ivy
-Ivy is a completion framework for Emacs, and my preferred (sometimes
-second favourite) one. It has a great set of features with little to
-no pain with setting up.
-**** Ivy Core
-Setup for ivy, in preparation for counsel. Turn on ivy-mode just
-after init.
-
-Setup vim-like bindings for the minibuffer ("M-(j|k)" for down|up the
-selection list).
-#+begin_src emacs-lisp
-(use-package ivy
- :defer t
- :hook (after-init-hook . ivy-mode)
- :general
- (general-def
- :keymaps 'ivy-minibuffer-map
- "C-j" #'ivy-yank-symbol
- "M-j" #'ivy-next-line-or-history
- "M-k" #'ivy-previous-line-or-history
- "C-c C-e" #'ivy-occur)
- (general-def
- :keymaps 'ivy-switch-buffer-map
- "M-j" #'ivy-next-line-or-history
- "M-k" #'ivy-previous-line-or-history)
- :config
- (require 'counsel nil t)
- (setq ivy-height 10
- ivy-wrap t
- ivy-fixed-height-minibuffer t
- ivy-use-virtual-buffers nil
- ivy-virtual-abbreviate 'full
- ivy-on-del-error-function #'ignore
- ivy-use-selectable-prompt t)
- (with-eval-after-load "amx"
- (setq amx-backend 'ivy)))
-#+end_src
-**** Counsel
-Setup for counsel. Load after ivy and helpful.
-
-Along with that, set the help function and variable functions to their
-helpful counterparts.
-#+begin_src emacs-lisp
-(use-package counsel
- :after ivy
- :general
- (search-leader
- "s" #'counsel-grep-or-swiper
- "r" #'counsel-rg)
- (file-leader
- "r" #'counsel-recentf)
- (insert-leader
- "c" #'counsel-unicode-char)
- (general-def
- [remap describe-bindings] #'counsel-descbinds
- [remap load-theme] #'counsel-load-theme)
- :config
- (setq ivy-initial-inputs-alist nil
- counsel-describe-function-function #'helpful-callable
- counsel-describe-variable-function #'helpful-variable
- counsel-grep-swiper-limit 1500000
- ivy-re-builders-alist '((swiper . ivy--regex-plus)
- (counsel-grep-or-swiper . ivy--regex-plus)
- (counsel-rg . ivy--regex-plus)
- (t . ivy--regex-ignore-order)))
- (counsel-mode))
-#+end_src
-**** Ivy posframe
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no
-:END:
-This makes ivy minibuffer windows use child frames. Very nice eyecandy.
-#+begin_src emacs-lisp
-(use-package ivy-posframe
- :hook (ivy-mode-hook . ivy-posframe-mode)
- :straight t
- :init
- (setq ivy-posframe-parameters
- '((left-fringe . 0)
- (right-fringe . 0)
- (background-color . "grey7")))
-
- (setq ivy-posframe-display-functions-alist
- '((t . ivy-posframe-display-at-window-center))))
-#+end_src
-**** Counsel etags
-:PROPERTIES:
-:header-args:emacs-lisp: :tangle no
-:END:
-Counsel etags allows me to search generated tag files for tags. I
-already have a function defined to generate the tags, so it's just
-searching them which I find to be a bit of a hassle, and where this
-package comes in.
-#+begin_src emacs-lisp
-(use-package counsel-etags
- :after counsel
- :general
- (search-leader
- "t" #'counsel-etags-find-tag))
-#+end_src
-*** Company
-Company is the auto complete system I use. I don't like having heavy
-setups for company as it only makes it slower to use. In this case,
-just setup some evil binds for company.
-#+begin_src emacs-lisp
-(use-package company
- :straight t
- :hook
- (prog-mode-hook . company-mode)
- (eshell-mode-hook . company-mode)
- :general
- (imap
- "C-SPC" #'company-complete)
- (general-def
- :states '(normal insert)
- "M-j" #'company-select-next
- "M-k" #'company-select-previous))
-#+end_src
-** Pretty symbols
-Prettify symbols mode allows for users to declare 'symbols' that
-replace text within certain modes. For example, you may replace the
-'for' word in c-mode for [[https://en.wikipedia.org/wiki/Universal_quantification][universal quantification]]. Though this may
-seem like useless eye candy, it has aided my comprehension and speed
-of recognition (recognising symbols is easier than words).
-
-Here I provide a macro +pretty/set-alist. This macro works pretty
-simply: given a mode hook, as well as a list of pairs typed (text to
-substitute, symbol to replace with). Then I add a hook to the given
-mode, setting the prettify-symbols-alist to the symbols given.
-
-I've declared it high up into my config so that the rest of my
-packages can leverage it. Furthermore I've added a use-package
-keyword which makes declaring this for language modes incredibly easy.
-Checkout my [[C/C++][C/C++]] configuration for an example.
-
-2023-03-08: I've removed the +pretty/set-alist macro and corresponding
-function as the use-package declaration is really enough.
-#+begin_src emacs-lisp
-(use-package prog-mode
- :straight nil
- :init
- (setq prettify-symbols-unprettify-at-point t)
- :config
- (with-eval-after-load "use-package-core"
- (add-to-list 'use-package-keywords ':pretty)
- (defun use-package-normalize/:pretty (_name-symbol _keyword args)
- args)
-
- (defun use-package-handler/:pretty (name _keyword args rest state)
- (use-package-concat
- (use-package-process-keywords name rest state)
- (let ((arg args)
- (forms nil))
- (while arg
- (let ((mode (caar arg))
- (rest (cdr (car arg))))
- (add-to-list
- 'forms
- `(add-hook
- ',mode
- (lambda nil
- (setq prettify-symbols-alist ',rest)
- (prettify-symbols-mode)))))
- (setq arg (cdr arg)))
- forms)))))
-#+end_src
-
-Here's a collection of symbols I have currently that may be used
-later.
-#+begin_example
-("null" . "Ø")
-("list" . "ℓ")
-("string" . "𝕊")
-("true" . "⊤")
-("false" . "⊥")
-("char" . "ℂ")
-("int" . "ℤ")
-("float" . "ℝ")
-("!" . "¬")
-("&&" . "∧")
-("||" . "∨")
-("for" . "∀")
-("return" . "⟼")
-("print" . "ℙ")
-("lambda" . "λ")
-#+end_example
-** Window management
-Window management is really important. I find the default window
-handling of Emacs incredibly annoying: sometimes consuming my windows,
-sometimes creating new ones. Of course, anything and everything is
-adaptable in Emacs, this behavior is no different.
-
-Here I create a use-package extension that manages the whole ordeal of
-adding a new record to the display-buffer-alist, a useful abstraction
-that makes it easy to manage the various buffers created by packages.
-I also provide bindings for buffer management.
-#+begin_src emacs-lisp
-(use-package window
- :straight nil
- :general
- (buffer-leader
- "b" #'switch-to-buffer
- "d" #'kill-current-buffer
- "K" #'kill-buffer
- "j" #'next-buffer
- "k" #'previous-buffer
- "D" '(+oreo/clean-buffer-list :which-key "Kill most buffers"))
- :init
- (with-eval-after-load "use-package-core"
- (add-to-list 'use-package-keywords ':display)
- (defun use-package-normalize/:display (_name-symbol _keyword args)
- args)
-
- (defun use-package-handler/:display (name _keyword args rest state)
- (use-package-concat
- (use-package-process-keywords name rest state)
- (let ((arg args)
- forms)
- (while arg
- (add-to-list 'forms
- `(add-to-list 'display-buffer-alist
- ',(car arg)))
- (setq arg (cdr arg)))
- forms)))))
-#+end_src
-*** Setup some display records
-Using the ~:display~ keyword, setup up some ~display-buffer-alist~
-records. This is mostly for packages that aren't really configured
-(like [[info:woman][woman]]) or packages that were configured before (like [[Ivy][Ivy]]).
-#+begin_src emacs-lisp
-(use-package window
- :straight nil
- :defer t
- :display
- ("\\*\\(Wo\\)?Man.*"
- (display-buffer-at-bottom)
- (window-height . 0.25))
-
- ("\\*Process List\\*"
- (display-buffer-at-bottom)
- (window-height . 0.25))
-
- ("\\*\\(Ido \\)?Completions\\*"
- (display-buffer-in-side-window)
- (window-height . 0.25)
- (side . bottom))
-
- ("\\*ivy-occur.*"
- (display-buffer-at-bottom)
- (window-height . 0.25))
-
- ("\\*Async Shell Command\\*"
- (display-buffer-at-bottom)
- (window-height . 0.25)))
-#+end_src
-** Auto typing
-Snippets are a system by which pieces of code can be inserted via
-prefixes. For example, an 'if' snippet would work by first inserting
-the word 'if' then pressing some _expansion key_ such as TAB. This
-will insert a set of text that may be have some components that need
-to be further filled by the user.
-
-The popular solution is Yasnippet. Yasnippet is a great package for
-snippets, which I use heavily in programming and org-mode. I setup
-here the global mode for yasnippet and a collection of snippets for
-ease of use.
-
-However, Emacs provides its own 'auto typing' facilities. Abbrevs and
-skeletons make up the popular solution within Emacs default. Abbrevs
-are for simple expressions wherein there is only one user input (say,
-getting today's time which only requires you asking for it). They
-provide a lot of inbuilt functionality and are quite useful.
-Skeletons, on the other hand, are for higher level insertions
-*** Abbrevs
-Just define a few abbrevs for various date-time operations. Also
-define a macro that will assume a function for the expansion, helping
-with abstracting a few things away.
-#+begin_src emacs-lisp
-(use-package abbrev
- :straight nil
- :hook
- (prog-mode-hook . abbrev-mode)
- (text-mode-hook . abbrev-mode)
- :init
- (defmacro +autotyping/deff-abbrev (ABBREV-TABLE ABBREV EXPANSION)
- "Wraps around define-abbrev to fill in some repeated stuff
-when expansion is a function."
- `(define-abbrev
- ,ABBREV-TABLE
- ,ABBREV
- ""
- (proc (insert ,EXPANSION))))
-
- (setq save-abbrevs nil)
- :config
- (+autotyping/deff-abbrev
- global-abbrev-table
- "sdate"
- (format-time-string "%Y-%m-%d" (current-time)))
-
- (+autotyping/deff-abbrev
- global-abbrev-table
- "stime"
- (format-time-string "%H:%M:%S" (current-time)))
-
- (+autotyping/deff-abbrev
- text-mode-abbrev-table
- "sday"
- (format-time-string "%A" (current-time)))
-
- (+autotyping/deff-abbrev
- text-mode-abbrev-table
- "smon"
- (format-time-string "%B" (current-time))))
-#+end_src
-*** Skeletons
-Defining some basic skeletons and a macro to help generate an abbrev
-as well.
-#+begin_src emacs-lisp
-(use-package skeleton
- :straight nil
- :after abbrev
- :config
- (defmacro +autotyping/gen-skeleton-abbrev (mode abbrev &rest skeleton)
- (let* ((table (intern (concat (symbol-name mode) "-abbrev-table")))
- (skeleton-name (intern (concat "+skeleton/" (symbol-name mode) "/" abbrev))))
- `(progn
- (define-skeleton
- ,skeleton-name
- ""
- ,@skeleton)
- (define-abbrev ,table
- ,abbrev
- ""
- ',skeleton-name)))))
-#+end_src
-*** Auto insert
-#+begin_src emacs-lisp
-(use-package autoinsert
- :straight nil
- :hook (after-init-hook . auto-insert-mode)
- :config
- (add-to-list
- 'auto-insert-alist
- '(("\\.html\\'" . "HTML Skeleton")
- ""
- "
-
-
-
-
- "(read-string "Enter title: ") | """
-
-
-
-
-
-
-
-
-
-
-
-"
- _
- "
-"))
- (add-to-list
- 'auto-insert-alist
- '(("Makefile" . "Makefile skeleton")
- ""
- "CC=g++
-CFLAGS=-Wall -ggdb
-OBJECTS=main.o
-OUT=main
-ARGS=
-
-%.o: %.cpp
- $(CC) $(CFLAGS) -c $^ -o $@
-
-$(OUT): $(OBJECTS)
- $(CC) $(CFLAGS) $^ -o $@
-
-.PHONY:
-clean:
- rm -rfv $(OUT) $(OBJECTS)
-
-.PHONY: run
-run: $(OUT)
- ./$^ $(ARGS)
-
-.PHONY: memcheck
-memcheck: $(OUT)
- sh /etc/profile.d/debuginfod.sh && valgrind --leak-check=full -s --tool=memcheck ./$^ $(ARGS)"
- _)))
-#+end_src
-*** Yasnippet default
-Setup global mode after evil mode has been loaded
-#+begin_src emacs-lisp
-(use-package yasnippet
- :after evil
- :hook
- (prog-mode-hook . yas-minor-mode)
- (text-mode-hook . yas-minor-mode)
- :general
- (insert-leader
- "i" #'yas-insert-snippet)
- :config
- (yas-load-directory (no-littering-expand-etc-file-name "yasnippet/snippets")))
-#+end_src
** Mode line
A mode line in an editor can provide a LOT of information, or very
little. I customised the Emacs modeline to give me a bit of info,
@@ -1157,36 +368,778 @@ with colouring and a ton of presentations to choose from.
(evil telephone-line-evil-tag-segment)))
(telephone-line-mode))
#+end_src
-** Olivetti
-Olivetti provides a focus mode for Emacs, which makes it look a bit
-nicer with fringes. I also define ~+olivetti-mode~ which will
-remember and clear up any window configurations on the frame, then
-when turned off will reinsert them - provides a nice way to quickly
-focus on a buffer.
+* Core packages
+Packages that are absolutely necessary for the rest of the
+configuration. These yield core functionality such as keybinding,
+modal editing, completion, auto typing to name a few.
+** General
+General provides a great solution for binding keys. It has evil and
+use-package support so it fits nicely into configuration. In this
+case, I define a "definer" for the "LEADER" keys. Leader is bound to
+~SPC~ and it's functionally equivalent to the doom/spacemacs leader.
+Local leader is bound to ~SPC ,~ and it's similar to doom/spacemacs
+leader but doesn't try to fully assimilate the local-leader map,
+instead just picking stuff I think is useful. This forces me to learn
+only as many bindings as I find necessary; no more, no less.
+
+I also define prefix leaders for differing applications. These are
+quite self explanatory by their name and provide a nice way to
+visualise all bindings under a specific heading just by searching the
+code.
#+begin_src emacs-lisp
-(use-package olivetti
- :commands (+olivetti-mode)
- :general
- (mode-leader
- "o" #'+olivetti-mode)
- :init
- (setq-default olivetti-body-width 0.6)
- (setq olivetti-style nil)
- (add-hook 'olivetti-mode-on-hook (proc (interactive) (text-scale-increase 1)))
- (add-hook 'olivetti-mode-off-hook (proc (interactive) (text-scale-decrease 1)))
+(use-package general
+ :demand t
:config
- (defun +olivetti-mode ()
- (interactive)
- (if (not olivetti-mode)
- (progn
- (window-configuration-to-register 1)
- (delete-other-windows)
- (olivetti-mode t))
- (jump-to-register 1)
- (olivetti-mode 0))))
+ ;; General which key definitions for leaders
+ (general-def
+ :states '(normal motion)
+ "SPC" nil
+ "SPC ," '(nil :which-key "Local leader")
+ "SPC c" '(nil :which-key "Code")
+ "SPC f" '(nil :which-key "File")
+ "SPC t" '(nil :which-key "Shell")
+ "SPC m" '(nil :which-key "Toggle modes")
+ "SPC a" '(nil :which-key "Applications")
+ "SPC s" '(nil :which-key "Search")
+ "SPC b" '(nil :which-key "Buffers")
+ "SPC q" '(nil :which-key "Quit/Literate")
+ "SPC i" '(nil :which-key "Insert")
+ "SPC d" '(nil :which-key "Directories"))
+
+ (general-create-definer leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC")
+
+ (general-create-definer local-leader
+ :states '(normal motion)
+ :prefix "SPC ,")
+
+ (general-create-definer code-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC c")
+
+ (general-create-definer file-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC f")
+
+ (general-create-definer shell-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC t")
+
+ (general-create-definer mode-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC m")
+
+ (general-create-definer app-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC a")
+
+ (general-create-definer search-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC s")
+
+ (general-create-definer buffer-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC b")
+
+ (general-create-definer quit-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC q")
+
+ (general-create-definer insert-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC i")
+
+ (general-create-definer dir-leader
+ :states '(normal motion)
+ :keymaps 'override
+ :prefix "SPC d")
+
+ (general-create-definer general-nmmap
+ :states '(normal motion))
+
+ (defalias 'nmmap #'general-nmmap)
+
+ (general-evil-setup t))
+#+end_src
+*** Some binds in Emacs
+Some bindings that I couldn't fit elsewhere easily.
+#+begin_src emacs-lisp
+(use-package emacs
+ :straight nil
+ :general
+ (general-def
+ "C-x d" #'delete-frame)
+
+ (nmmap
+ "C--" #'text-scale-decrease
+ "C-=" #'text-scale-increase)
+
+ (leader
+ "SPC" '(execute-extended-command :which-key "M-x")
+ "'" '(browse-url-emacs :which-key "Open url in Emacs")
+ "u" 'universal-argument
+ ";" 'eval-expression
+ ":" `(,(proc (interactive) (switch-to-buffer "*scratch*"))
+ :which-key "Switch to *scratch*")
+ "!" '(async-shell-command :which-key "Async shell command")
+ "h" '(help-command :which-key "Help"))
+
+ (code-leader
+ "j" #'next-error
+ "k" #'previous-error
+ "c" #'compile
+ "C" #'recompile
+ "F" (list (proc (interactive) (find-file "~/Code/")) ':which-key "Open ~/Code/"))
+
+ (file-leader
+ "f" #'find-file
+ "F" #'find-file-other-frame
+ "s" #'save-buffer
+ "p" (list (proc (interactive) (find-file (concat user-emacs-directory "config.org")))
+ ':which-key "Open config.org"))
+
+ (quit-leader
+ "q" #'save-buffers-kill-terminal
+ "c" #'+literate/compile-config
+ "l" #'+literate/load-config
+ "d" #'delete-frame)
+
+ (search-leader "i" #'imenu))
+#+end_src
+** Evil
+My editor journey started off with Vim rather than Emacs, so my brain
+has imprinted on its style. Thankfully Emacs is super extensible so
+there exists a package (more of a supreme system) for porting Vim's
+modal editing style to Emacs, called Evil (Emacs Vi Layer).
+
+However there are a lot of packages in Vim that provide greater
+functionality, for example 'vim-surround'. Emacs, by default, has
+these capabilities but there are further packages which integrate them
+into Evil.
+*** Evil core
+Setup the evil package, with some opinionated keybindings:
+- Switch ~evil-upcase~ and ~evil-downcase~ because I use ~evil-upcase~
+ more
+- Switch ~evil-goto-mark~ and ~evil-goto-mark-line~ as I'd rather have
+ the global one closer to the home row
+- Use 'T' character as an action for transposing objects
+#+begin_src emacs-lisp
+(use-package evil
+ :demand t
+ :hook (after-init-hook . evil-mode)
+ :general
+ (leader
+ "w" '(evil-window-map :which-key "Window")
+ "wd" #'delete-frame)
+
+ (nmmap
+ "TAB" #'evil-jump-item
+ "r" #'evil-replace-state
+ "zC" #'hs-hide-level
+ "'" #'evil-goto-mark
+ "`" #'evil-goto-mark-line
+ "C-w" #'evil-window-map
+ "gu" #'evil-upcase
+ "gU" #'evil-downcase
+ "T" nil)
+
+ (nmmap
+ :infix "T"
+ "w" #'transpose-words
+ "c" #'transpose-chars
+ "s" #'transpose-sentences
+ "p" #'transpose-paragraphs
+ "e" #'transpose-sexps
+ "l" #'transpose-lines)
+ :init
+ (setq evil-want-keybinding nil
+ evil-split-window-below t
+ evil-vsplit-window-right t
+ evil-want-abbrev-expand-on-insert-exit t
+ evil-undo-system #'undo-tree)
+ :config
+ (fset #'evil-window-vsplit #'make-frame))
+#+end_src
+*** Evil surround
+Evil surround is a port for vim-surround.
+#+begin_src emacs-lisp
+(use-package evil-surround
+ :after evil
+ :config
+ (global-evil-surround-mode))
+#+end_src
+*** Evil commentary
+Allows generalised commenting of objects easily.
+#+begin_src emacs-lisp
+(use-package evil-commentary
+ :after evil
+ :config
+ (evil-commentary-mode))
+#+end_src
+*** Evil multi cursor
+Setup for multi cursors in Evil mode. Don't let evil-mc setup it's own
+keymap because it uses 'gr' as its prefix, which I don't like.
+#+begin_src emacs-lisp
+(use-package evil-mc
+ :after evil
+ :init
+ (defvar evil-mc-key-map (make-sparse-keymap))
+ :general
+ (nmap
+ :infix "gz"
+ "q" #'evil-mc-undo-all-cursors
+ "d" #'evil-mc-make-and-goto-next-match
+ "j" #'evil-mc-make-cursor-move-next-line
+ "k" #'evil-mc-make-cursor-move-prev-line
+ "j" #'evil-mc-make-cursor-move-next-line
+ "m" #'evil-mc-make-all-cursors
+ "z" #'evil-mc-make-cursor-here
+ "r" #'evil-mc-resume-cursors
+ "s" #'evil-mc-pause-cursors
+ "u" #'evil-mc-undo-last-added-cursor)
+ :config
+ ;; (evil-mc-define-vars)
+ ;; (evil-mc-initialize-vars)
+ ;; (add-hook 'evil-mc-before-cursors-created #'evil-mc-pause-incompatible-modes)
+ ;; (add-hook 'evil-mc-before-cursors-created #'evil-mc-initialize-active-state)
+ ;; (add-hook 'evil-mc-after-cursors-deleted #'evil-mc-teardown-active-state)
+ ;; (add-hook 'evil-mc-after-cursors-deleted #'evil-mc-resume-incompatible-modes)
+ ;; (advice-add #'evil-mc-initialize-hooks :override #'ignore)
+ ;; (advice-add #'evil-mc-teardown-hooks :override #'evil-mc-initialize-vars)
+ ;; (advice-add #'evil-mc-initialize-active-state :before #'turn-on-evil-mc-mode)
+ ;; (advice-add #'evil-mc-teardown-active-state :after #'turn-off-evil-mc-mode)
+ ;; (add-hook 'evil-insert-state-entry-hook #'evil-mc-resume-cursors)
+ (global-evil-mc-mode))
+#+end_src
+
+*** Evil collection
+Provides a community based set of keybindings for most modes in
+Emacs. I don't necessarily like all my modes having these bindings
+though, as I may disagree with some. So I use it in a mode to mode basis.
+#+begin_src emacs-lisp
+(use-package evil-collection
+ :after evil)
+#+end_src
+** Completion
+Emacs is a text based interface. Completion is its bread and butter
+in providing good user experience. By default Emacs provides
+'completions-list' which produces a buffer of options which can be
+searched and selected. We can take this further though!
+
+Ido and Icomplete are packages distributed with Emacs to provide
+greater completion interfaces. They utilise the minibuffer to create
+a more interactive experience, allowing incremental searches and
+option selection.
+
+Ivy and Helm provide more modern interfaces, though Helm is quite
+heavy. Ivy, on the other hand, provides an interface similar to Ido
+with less clutter and better customisation options.
+*** Ivy
+Ivy is a completion framework for Emacs, and my preferred one. It has
+a great set of features with little to no pain with setting up.
+**** Ivy Core
+Setup for ivy, in preparation for counsel. Turn on ivy-mode just
+after init.
+
+Setup vim-like bindings for the minibuffer ("M-(j|k)" for down|up the
+selection list).
+#+begin_src emacs-lisp
+(use-package ivy
+ :defer t
+ :hook (after-init-hook . ivy-mode)
+ :general
+ (general-def
+ :keymaps 'ivy-minibuffer-map
+ "C-j" #'ivy-yank-symbol
+ "M-j" #'ivy-next-line-or-history
+ "M-k" #'ivy-previous-line-or-history
+ "C-c C-e" #'ivy-occur)
+ (general-def
+ :keymaps 'ivy-switch-buffer-map
+ "M-j" #'ivy-next-line-or-history
+ "M-k" #'ivy-previous-line-or-history)
+ :config
+ (require 'counsel nil t)
+ (setq ivy-height 10
+ ivy-wrap t
+ ivy-fixed-height-minibuffer t
+ ivy-use-virtual-buffers nil
+ ivy-virtual-abbreviate 'full
+ ivy-on-del-error-function #'ignore
+ ivy-use-selectable-prompt t)
+ (with-eval-after-load "amx"
+ (setq amx-backend 'ivy)))
+#+end_src
+**** Counsel
+Setup for counsel. Load after ivy and helpful.
+#+begin_src emacs-lisp
+(use-package counsel
+ :after ivy
+ :general
+ (search-leader
+ "s" #'counsel-grep-or-swiper
+ "r" #'counsel-rg)
+ (file-leader
+ "r" #'counsel-recentf)
+ (insert-leader
+ "c" #'counsel-unicode-char)
+ (general-def
+ [remap describe-bindings] #'counsel-descbinds
+ [remap load-theme] #'counsel-load-theme)
+ :config
+ (setq ivy-initial-inputs-alist nil
+ counsel-describe-function-function #'helpful-callable
+ counsel-describe-variable-function #'helpful-variable
+ counsel-grep-swiper-limit 1500000
+ ivy-re-builders-alist '((swiper . ivy--regex-plus)
+ (counsel-grep-or-swiper . ivy--regex-plus)
+ (counsel-rg . ivy--regex-plus)
+ (t . ivy--regex-ignore-order)))
+ (counsel-mode))
+#+end_src
+**** Ivy posframe
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no
+:END:
+This makes ivy minibuffer windows use child frames. Very nice eyecandy.
+#+begin_src emacs-lisp
+(use-package ivy-posframe
+ :hook (ivy-mode-hook . ivy-posframe-mode)
+ :straight t
+ :init
+ (setq ivy-posframe-parameters
+ '((left-fringe . 0)
+ (right-fringe . 0)
+ (background-color . "grey7")))
+
+ (setq ivy-posframe-display-functions-alist
+ '((t . ivy-posframe-display-at-window-center))))
+#+end_src
+**** Counsel etags
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no
+:END:
+Counsel etags allows me to search generated tag files for tags. I
+already have a function defined to generate the tags, so it's just
+searching them which I find to be a bit of a hassle, and where this
+package comes in.
+
+This has been replaced by [[*xref][xref]] which is inbuilt.
+#+begin_src emacs-lisp
+(use-package counsel-etags
+ :after counsel
+ :general
+ (search-leader
+ "t" #'counsel-etags-find-tag))
+#+end_src
+*** Ido
+:PROPERTIES:
+:header-args:emacs-lisp: :tangle no
+:END:
+Ido is a very old completion package that still works great to this
+day. Though it is limited in its scope (and may thus be called a
+completion add-on rather than a full on framework), it is still a very
+powerful package. With the use of ido-completing-read+, it may be used
+similarly to a fully fledged completion framework.
+
+#+begin_src emacs-lisp
+(use-package ido
+ :demand t
+ :general
+ (general-def
+ :keymaps '(ido-buffer-completion-map
+ ido-file-completion-map
+ ido-file-dir-completion-map
+ ido-common-completion-map)
+ (kbd "M-j") #'ido-next-match
+ (kbd "M-k") #'ido-prev-match
+ (kbd "C-x o") #'evil-window-up)
+ :init
+ (setq ido-decorations
+ (list "{" "}" " \n" " ..." "[" "]" " [No match]" " [Matched]"
+ " [Not readable]" " [Too big]" " [Confirm]")
+ completion-styles '(flex partial-completion intials emacs22))
+ (setq-default ido-enable-flex-matching t
+ ido-enable-dot-prefix t
+ ido-enable-regexp nil)
+ (with-eval-after-load "magit"
+ (setq magit-completing-read-function 'magit-ido-completing-read))
+ :config
+ (ido-mode)
+ (ido-everywhere))
+#+end_src
+**** Ido ubiquitous
+Ido completing-read+ is a package that extends the ido package to work
+with more text based functions.
+#+begin_src emacs-lisp
+(use-package ido-completing-read+
+ :after ido
+ :config
+ (ido-ubiquitous-mode +1))
+#+end_src
+*** Amx
+Amx is a fork of Smex that works to enhance the
+execute-extended-command interface. It also provides support for ido
+or ivy (though I'm likely to use ido here) and allows you to switch
+between them.
+
+It provides a lot of niceties such as presenting the key bind when
+looking for a command.
+
+#+begin_src emacs-lisp
+(use-package amx
+ :config
+ (amx-mode))
+#+end_src
+*** Orderless
+Orderless sorting method for completion, probably one of the best
+things ever.
+#+begin_src emacs-lisp
+(use-package orderless
+ :after (ivy ido)
+ :config
+ (setf (alist-get t ivy-re-builders-alist) 'orderless-ivy-re-builder))
+#+end_src
+*** Completions-list
+In case I ever use the completions list, some basic commands to look
+around.
+#+begin_src emacs-lisp
+(use-package simple
+ :straight nil
+ :general
+ (nmmap
+ :keymaps 'completion-list-mode-map
+ "l" #'next-completion
+ "h" #'previous-completion
+ "ESC" #'delete-completion-window
+ "q" #'quit-window
+ "RET" #'choose-completion)
+ :config
+ (with-eval-after-load "evil"
+ (setq evil-emacs-state-modes (cl-remove-if
+ #'(lambda (x) (eq 'completions-list-mode x))
+ evil-emacs-state-modes))
+ (add-to-list 'evil-normal-state-modes 'completions-list-mode)))
+#+end_src
+*** Company
+Company is the auto complete system I use. I don't like having heavy
+setups for company as it only makes it slower to use. In this case,
+just setup some evil binds for company.
+#+begin_src emacs-lisp
+(use-package company
+ :straight t
+ :hook
+ (prog-mode-hook . company-mode)
+ (eshell-mode-hook . company-mode)
+ :general
+ (imap
+ "C-SPC" #'company-complete)
+ (general-def
+ :states '(normal insert)
+ "M-j" #'company-select-next
+ "M-k" #'company-select-previous))
+#+end_src
+** Pretty symbols
+Prettify symbols mode allows for users to declare 'symbols' that
+replace text within certain modes. Though this may seem like useless
+eye candy, it has aided my comprehension and speed of recognition
+(recognising symbols is easier than words).
+
+Essentially a use-package keyword which makes declaring pretty symbols
+for language modes incredibly easy. Checkout my [[C/C++][C/C++]] configuration
+for an example.
+#+begin_src emacs-lisp
+(use-package prog-mode
+ :straight nil
+ :init
+ (setq prettify-symbols-unprettify-at-point t)
+ :config
+ (with-eval-after-load "use-package-core"
+ (add-to-list 'use-package-keywords ':pretty)
+ (defun use-package-normalize/:pretty (_name-symbol _keyword args)
+ args)
+
+ (defun use-package-handler/:pretty (name _keyword args rest state)
+ (use-package-concat
+ (use-package-process-keywords name rest state)
+ (let ((arg args)
+ (forms nil))
+ (while arg
+ (let ((mode (caar arg))
+ (rest (cdr (car arg))))
+ (add-to-list
+ 'forms
+ `(add-hook
+ ',mode
+ (lambda nil
+ (setq prettify-symbols-alist ',rest)
+ (prettify-symbols-mode)))))
+ (setq arg (cdr arg)))
+ forms)))))
+#+end_src
+
+Here's a collection of keywords and their associated symbols, for a
+pseudo language.
+#+begin_example
+("null" . "Ø")
+("list" . "ℓ")
+("string" . "𝕊")
+("true" . "⊤")
+("false" . "⊥")
+("char" . "ℂ")
+("int" . "ℤ")
+("float" . "ℝ")
+("!" . "¬")
+("&&" . "∧")
+("||" . "∨")
+("for" . "∀")
+("return" . "⟼")
+("print" . "ℙ")
+("lambda" . "λ")
+#+end_example
+** Window management
+Emacs' default window management is quite bad, eating other windows
+and not particularly caring for the current window setup. Thankfully
+you can change this via the ~display-buffer-alist~ which matches
+buffer names with how the window for the buffer should be displayed.
+I add a use-package keyword to make ~display-buffer-alist~ records
+within use-package.
+#+begin_src emacs-lisp
+(use-package window
+ :straight nil
+ :general
+ (buffer-leader
+ "b" #'switch-to-buffer
+ "d" #'kill-current-buffer
+ "K" #'kill-buffer
+ "j" #'next-buffer
+ "k" #'previous-buffer
+ "D" '(+oreo/clean-buffer-list :which-key "Kill most buffers"))
+ :init
+ (with-eval-after-load "use-package-core"
+ (add-to-list 'use-package-keywords ':display)
+ (defun use-package-normalize/:display (_name-symbol _keyword args)
+ args)
+
+ (defun use-package-handler/:display (name _keyword args rest state)
+ (use-package-concat
+ (use-package-process-keywords name rest state)
+ (let ((arg args)
+ forms)
+ (while arg
+ (add-to-list 'forms
+ `(add-to-list 'display-buffer-alist
+ ',(car arg)))
+ (setq arg (cdr arg)))
+ forms)))))
+#+end_src
+*** Some display records
+Using the ~:display~ keyword, setup up some ~display-buffer-alist~
+records. This is mostly for packages that aren't really configured
+(like [[info:woman][woman]]) or packages that were configured before (like [[Ivy][Ivy]]).
+#+begin_src emacs-lisp
+(use-package window
+ :straight nil
+ :defer t
+ :display
+ ("\\*\\(Wo\\)?Man.*"
+ (display-buffer-at-bottom)
+ (window-height . 0.25))
+
+ ("\\*Process List\\*"
+ (display-buffer-at-bottom)
+ (window-height . 0.25))
+
+ ("\\*\\(Ido \\)?Completions\\*"
+ (display-buffer-in-side-window)
+ (window-height . 0.25)
+ (side . bottom))
+
+ ("\\*ivy-occur.*"
+ (display-buffer-at-bottom)
+ (window-height . 0.25))
+
+ ("\\*Async Shell Command\\*"
+ (display-buffer-at-bottom)
+ (window-height . 0.25)))
+#+end_src
+** Auto typing
+Snippets are a pretty nice way of automatically inserting code. Emacs
+provides a ton of packages by default to do this, but there are great
+packages to install as well.
+
+Abbrevs and skeletons make up a popular solution within Emacs default.
+Abbrevs are for simple expressions wherein the only input is the key,
+and the output is some Elisp function. They provide a lot of inbuilt
+functionality and are quite useful. Skeletons, on the other hand, are
+for higher level insertions
+
+The popular external solution is Yasnippet. Yasnippet is a great
+package for snippets, which I use heavily in programming and org-mode.
+I setup here the global mode for yasnippet and a collection of
+snippets for ease of use.
+*** Abbrevs
+Just define a few abbrevs for various date-time operations. Also
+define a macro that will assume a function for the expansion, helping
+with abstracting a few things away.
+#+begin_src emacs-lisp
+(use-package abbrev
+ :straight nil
+ :hook
+ (prog-mode-hook . abbrev-mode)
+ (text-mode-hook . abbrev-mode)
+ :init
+ (defmacro +autotyping/deff-abbrev (ABBREV-TABLE ABBREV EXPANSION)
+ "Wraps around define-abbrev to fill in some repeated stuff
+when expansion is a function."
+ `(define-abbrev
+ ,ABBREV-TABLE
+ ,ABBREV
+ ""
+ (proc (insert ,EXPANSION))))
+
+ (setq save-abbrevs nil)
+ :config
+ (+autotyping/deff-abbrev
+ global-abbrev-table
+ "sdate"
+ (format-time-string "%Y-%m-%d" (current-time)))
+
+ (+autotyping/deff-abbrev
+ global-abbrev-table
+ "stime"
+ (format-time-string "%H:%M:%S" (current-time)))
+
+ (+autotyping/deff-abbrev
+ text-mode-abbrev-table
+ "sday"
+ (format-time-string "%A" (current-time)))
+
+ (+autotyping/deff-abbrev
+ text-mode-abbrev-table
+ "smon"
+ (format-time-string "%B" (current-time))))
+#+end_src
+*** Skeletons
+Defining some basic skeletons and a macro to help generate an abbrev
+as well.
+#+begin_src emacs-lisp
+(use-package skeleton
+ :straight nil
+ :after abbrev
+ :config
+ (defmacro +autotyping/gen-skeleton-abbrev (mode abbrev &rest skeleton)
+ (let* ((table (intern (concat (symbol-name mode) "-abbrev-table")))
+ (skeleton-name (intern (concat "+skeleton/" (symbol-name mode) "/" abbrev))))
+ `(progn
+ (define-skeleton
+ ,skeleton-name
+ ""
+ ,@skeleton)
+ (define-abbrev ,table
+ ,abbrev
+ ""
+ ',skeleton-name)))))
+#+end_src
+*** Auto insert
+Allows inserting text on creating of a new buffer with a given name.
+Supports skeletons for inserting text. Here I define an HTML skeleton
+and a Makefile skeleton.
+#+begin_src emacs-lisp
+(use-package autoinsert
+ :straight nil
+ :hook (after-init-hook . auto-insert-mode)
+ :config
+ (add-to-list
+ 'auto-insert-alist
+ '(("\\.html\\'" . "HTML Skeleton")
+ ""
+ "
+
+
+
+
+ "(read-string "Enter title: ") | """
+
+
+
+
+
+
+
+
+
+
+
+"
+ _
+ "
+"))
+ (add-to-list
+ 'auto-insert-alist
+ '(("Makefile" . "Makefile skeleton")
+ ""
+ "CC=g++
+CFLAGS=-Wall -ggdb
+OBJECTS=main.o
+OUT=main
+ARGS=
+
+%.o: %.cpp
+ $(CC) $(CFLAGS) -c $^ -o $@
+
+$(OUT): $(OBJECTS)
+ $(CC) $(CFLAGS) $^ -o $@
+
+.PHONY:
+clean:
+ rm -rfv $(OUT) $(OBJECTS)
+
+.PHONY: run
+run: $(OUT)
+ ./$^ $(ARGS)
+
+.PHONY: memcheck
+memcheck: $(OUT)
+ sh /etc/profile.d/debuginfod.sh && valgrind --leak-check=full -s --tool=memcheck ./$^ $(ARGS)"
+ _)))
+#+end_src
+*** Yasnippet default
+Look at the snippets [[file:.config/yasnippet/snippets/][folder]] for all snippets I've got.
+#+begin_src emacs-lisp
+(use-package yasnippet
+ :after evil
+ :hook
+ (prog-mode-hook . yas-minor-mode)
+ (text-mode-hook . yas-minor-mode)
+ :general
+ (insert-leader
+ "i" #'yas-insert-snippet)
+ :config
+ (yas-load-directory (no-littering-expand-etc-file-name "yasnippet/snippets")))
#+end_src
* Small packages
** ISearch
+ISearch is the default incremental search application in Emacs. I use
+~evil-search-forward~ so I don't interact with isearch that much, but
+I may need it occasionally.
#+begin_src emacs-lisp
(use-package isearch
:straight nil
@@ -1195,6 +1148,8 @@ focus on a buffer.
"M-s" #'isearch-repeat-forward))
#+end_src
** Info
+Info is GNU's attempt at better man pages. Most Emacs packages have
+info pages so I'd like nice navigation options.
#+begin_src emacs-lisp
(use-package info
:straight nil
@@ -1208,9 +1163,10 @@ focus on a buffer.
"L" #'Info-history-forward))
#+end_src
** Display line numbers
-I don't like using this mode by default, but I'd like to configure it
-if possible. Line numbers are a necessary evil a lot of times, and
-it's useful for presentations.
+I don't really like line numbers, I find them similar to [[*Fringes][fringes]] as
+useless space, but at least it provides some information. Sometimes
+it can help with doing repeated commands so a toggle option is
+necessary.
#+begin_src emacs-lisp
(use-package display-line-numbers
:straight nil
@@ -1221,22 +1177,26 @@ it's useful for presentations.
:init
(setq-default display-line-numbers-type 'relative))
#+end_src
-** esup (profiling)
+** esup
I used to be able to just use [[file:elisp/profiler-dotemacs.el][profile-dotemacs.el]], when my Emacs
config was smaller, but now it tells me very little information about
-where my setup is inefficient. Just found this ~esup~ thing and it
-works perfectly, exactly how I would prefer getting this kind of
-information.
+where my setup is inefficient due to the literate config. Just found
+this ~esup~ thing and it works perfectly, exactly how I would prefer
+getting this kind of information. It runs an external Emacs instance
+and collects information from it, so it doesn't require restarting
+Emacs to profile.
#+begin_src emacs-lisp
(use-package esup
:defer t)
#+end_src
** xref
-Find definitions, references using tags for free! Such an underrated
-utility, particularly now that I'm not using Eglot (in some sense,
-returning to the nature of Emacs). All you need is a way of
-generating tags, probably a make recipe.
+Find definitions, references and general objects using tags without
+external packages. Provided by default in Emacs and just requires a
+way of generating a =TAGS= file for your project. Helps with minimal
+setups for programming without heavier packages like [[*Eglot][Eglot]].
+
+[[*Projectile][Projectile]] provides a nice way to generate tags.
#+begin_src emacs-lisp
(use-package xref
:straight nil
@@ -1262,21 +1222,24 @@ generating tags, probably a make recipe.
"q" #'quit-window))
#+end_src
** Hl-line
-Hl-line is a useful tool, best line indicator in the game.
+Highlights the current line, much better than a blinking cursor.
#+begin_src emacs-lisp
(use-package hl-line
:defer t
:hook (text-mode-hook . hl-line-mode))
#+end_src
** Recentf
-Recentf makes it easy to
+Recentf provides a method of keeping track of recently opened files.
#+begin_src emacs-lisp
(use-package recentf
:straight nil
:hook (emacs-startup-hook . recentf-mode))
#+end_src
** Projectile
-Setup projectile, along with the tags command.
+Projectile is a project management package which integrates with Emacs
+very well. It essentially provides alternative Emacs commands scoped
+to the current 'project', based on differing signs that a directory is
+a 'project'.
#+begin_src emacs-lisp
(use-package projectile
:after evil
@@ -1287,8 +1250,7 @@ Setup projectile, along with the tags command.
(setq projectile-tags-command "ctags -Re -f \"%s\" %s \"%s\""))
#+end_src
*** Counsel projectile
-Counsel projectile provides the ivy interface to projectile commands,
-which is really useful.
+Counsel integration for projectile commands, very nice.
#+begin_src emacs-lisp
(use-package counsel-projectile
:after (projectile counsel)
@@ -1303,17 +1265,16 @@ need to use it.
(use-package avy
:after evil
:general
- (search-leader
- "l" #'avy-goto-line)
(nmmap
- (kbd "C-s") #'avy-goto-char-timer
- (kbd "M-s") #'isearch-forward))
+ "C-s" #'avy-goto-char-timer
+ "M-s" #'isearch-forward)
+ (search-leader
+ "l" #'avy-goto-line))
#+end_src
** Ace window
Though evil provides a great many features in terms of window
-management, much greater than what's easily available in Emacs, ace
-window can provide some nicer chords for higher management of windows
-(closing, switching, etc).
+management, ace window can provide some nicer chords for higher
+management of windows (closing, switching, etc).
#+begin_src emacs-lisp
(use-package ace-window
@@ -1325,8 +1286,9 @@ window can provide some nicer chords for higher management of windows
[remap evil-window-next] #'ace-window))
#+end_src
** Helpful
-Basic setup that replaces commands and configures
-~display-buffer-alist~ for helpful.
+Helpful provides a modernised interface for some common help
+commands. I replace ~describe-function~, ~describe-variable~ and
+~describe-key~ by their helpful counterparts.
#+begin_src emacs-lisp
(use-package helpful
:after ivy
@@ -1345,7 +1307,8 @@ Basic setup that replaces commands and configures
(evil-define-key 'normal helpful-mode-map "q" #'quit-window))
#+end_src
** Which-key
-Pretty simple, just activate after init.
+Which key uses the minibuffer when performing a keybind to provide
+possible options for the next key.
#+begin_src emacs-lisp
(use-package which-key
:config
@@ -1353,7 +1316,7 @@ Pretty simple, just activate after init.
#+end_src
** Keychord
Keychord is only really here for this one chord I wish to define: "jk"
-for exiting insert state. Otherwise, I don't really need it.
+for exiting insert state.
#+begin_src emacs-lisp
(use-package key-chord
:after evil
@@ -1362,35 +1325,27 @@ for exiting insert state. Otherwise, I don't really need it.
(key-chord-mode))
#+end_src
** (Rip)grep
-Grep is likely one of the most important programs ever invented; a
-must-have tool for any Linux users inventory. It is a searching
-utility that allows one to search files for certain regex patterns.
-The fact that there have been so many attempts to replace grep (with
-limited success) only goes to show how important its general function
-is to people.
+Grep is a great piece of software, a necessary tool in any Linux
+user's inventory. By default Emacs has a family of functions to use
+grep, presenting results in a ~compilation~ style. ~grep~ searches
+files, ~rgrep~ searches in a directory using the ~find~ program and
+~zgrep~ searches archives. This is a great solution for a general
+computer environment; essentially all Linux installs will have ~grep~
+and ~find~ installed.
-Ripgrep is a grep-like utility written in Rust. It subsumes not only
-the ability to search a given file but also to search multiple files
-within a directory (which is usually only done by composing the
-program find with grep to search multiple files). It is incredibly
-fast by virtue of its regex optimisations and the use of ignore files
-such as ~.gitignore~ to filter files when searching.
+Ripgrep is a Rust program that attempts to perform better than grep,
+and it actually does. This is because of a set of optimisations, such
+as checking the =.gitignore= to exclude certain files from being
+searched. The ripgrep package provides utilities to ripgrep projects
+and files for strings. Though [[*Ivy][ivy]] comes with ~counsel-rg~, it uses
+Ivy's completion framework rather than the ~compilation~ style
+buffers, which sometimes proves very useful.
-Grep has default Emacs utilities that use a ~compilation~ style buffer
-to search a variety of differing data sets. ~grep~ searches files,
-~rgrep~ searches in a directory using the ~find~ binary and ~zgrep~
-searches archives. This is a great solution for most computer
-environments as basically all of them will have grep and find
-installed. Even when you ~ssh~ into a remote machine, they're likely
-to have these tools.
-
-The ripgrep package provides utilities to ripgrep projects and files
-for strings via the rg binary. Though [[*Ivy][ivy]] comes with ~counsel-rg~
-using it makes me dependent on the ivy framework, and this
-configuration is intentionally built to be modular and switchable. Of
-course, this requires installing the rg binary which is available in
-most repositories nowadays.
+Of course, this requires installing the rg binary which is available
+in most repositories nowadays.
*** Grep
+I have no use for standard 'grep'; ~counsel-swiper~ does the same
+thing faster and within Emacs lisp. ~rgrep~ is useful though.
#+begin_src emacs-lisp
(use-package grep
:display
@@ -1423,6 +1378,34 @@ most repositories nowadays.
rg-default-alias-fallback "all"
rg-buffer-name "*ripgrep*"))
#+end_src
+** Olivetti
+Olivetti provides a focus mode for Emacs, which makes it look a bit
+nicer with fringes. I also define ~+olivetti-mode~ which will
+remember and clear up any window configurations on the frame, then
+when turned off will reinsert them - provides a nice way to quickly
+focus on a buffer.
+#+begin_src emacs-lisp
+(use-package olivetti
+ :commands (+olivetti-mode)
+ :general
+ (mode-leader
+ "o" #'+olivetti-mode)
+ :init
+ (setq-default olivetti-body-width 0.6)
+ (setq olivetti-style nil)
+ (add-hook 'olivetti-mode-on-hook (proc (interactive) (text-scale-increase 1)))
+ (add-hook 'olivetti-mode-off-hook (proc (interactive) (text-scale-decrease 1)))
+ :config
+ (defun +olivetti-mode ()
+ (interactive)
+ (if (not olivetti-mode)
+ (progn
+ (window-configuration-to-register 1)
+ (delete-other-windows)
+ (olivetti-mode t))
+ (jump-to-register 1)
+ (olivetti-mode 0))))
+#+end_src
** All the Icons
Nice set of icons with a great user interface to manage them.
#+begin_src emacs-lisp
@@ -1457,9 +1440,13 @@ at last.
(save-place-mode))
#+end_src
* Applications
+Applications are greater than packages; they provide a set of
+functionality to create an interface in Emacs. Emacs comes with
+applications and others may be installed.
** Dashboard
Dashboard creates a custom dashboard for Emacs that replaces the
-initial startup screen in default Emacs.
+initial startup screen in default Emacs. It has a lot of customising
+options.
#+begin_src emacs-lisp
(use-package dashboard
:straight t
@@ -1499,18 +1486,24 @@ initial startup screen in default Emacs.
(dashboard-setup-startup-hook))
#+end_src
** EWW
+Emacs Web Wowser is the inbuilt text based web browser for Emacs. It
+can render images and basic CSS styles but doesn't have a JavaScript
+engine, which makes sense as it's primarily a text interface.
#+begin_src emacs-lisp
(use-package eww
:defer t
+ :general
+ (app-leader
+ "w" #'eww)
:straight nil
:config
(with-eval-after-load "evil-collection"
(evil-collection-eww-setup)))
#+end_src
** Calendar
-Calendar is a simple inbuilt application within Emacs that helps with
-date functionalities. I add functionality to copy dates from the
-calendar to the kill ring and bind it to "Y".
+Calendar is a simple inbuilt application that helps with date
+functionalities. I add functionality to copy dates from the calendar
+to the kill ring and bind it to "Y".
#+begin_src emacs-lisp
(use-package calendar
:straight nil
@@ -2016,6 +2009,9 @@ don't need to write everything myself.
(display-buffer-same-window))
:general
(leader "g" '(magit-status :which-key "Magit"))
+ (nmmap
+ :keymaps 'magit-status-mode-map
+ "TAB" #'magit-section-toggle)
:init
(setq vc-follow-symlinks t)
(with-eval-after-load "autoinsert"
@@ -2025,6 +2021,8 @@ don't need to write everything myself.
(read-string "Enter simple description: ") "\n\n"
_)))
:config
+ (with-eval-after-load "evil"
+ (evil-set-initial-state 'magit-status-mode 'motion))
(with-eval-after-load "evil-collection"
(evil-collection-magit-setup)))
#+end_src
@@ -2165,8 +2163,13 @@ Of course Emacs has a cool screensaver software.
Colourising the compilation buffer so ANSI colour codes get computed.
#+begin_src emacs-lisp
(use-package compile
- :defer t
:straight nil
+ :general
+ (code-leader
+ "j" #'next-error
+ "k" #'previous-error
+ "c" #'compile
+ "C" #'recompile)
:display
("\\*compilation\\*"
(display-buffer-at-bottom)
@@ -2179,10 +2182,9 @@ Colourising the compilation buffer so ANSI colour codes get computed.
(ansi-color-apply-on-region (point-min) (point-max))))
(add-hook 'compilation-filter-hook #'+compile/colourise))
#+end_src
-* Major modes, programming and text
-Setups for common major modes and languages.
-** Text Configuration
-Standard packages and configurations for the text-mode.
+* Text modes
+Standard packages and configurations for text-mode and its derived
+modes.
*** Flyspell
Flyspell allows me to quickly spell check text documents. I use
flyspell primarily in org mode, as that is my preferred prose writing
@@ -2239,7 +2241,9 @@ limit), so set it for specific modes need the help.
whitespace-line-column 80))
#+end_src
*** Set auto-fill-mode for all text-modes
-Auto fill mode is nice for most text modes, 80 char limit is great.
+Auto fill mode automatically newlines text on 80 characters, which
+looks nice and integrates well with Evil's sentence and paragraph text
+objects.
#+begin_src emacs-lisp
(add-hook 'text-mode-hook #'auto-fill-mode)
#+end_src
@@ -2270,8 +2274,10 @@ context and easier to use.
(sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p))
(require 'smartparens-config))
#+end_src
-** Programming Configuration
-*** Eldoc
+* Programming modes
+Packages that help with programming in general, providing IDE like
+capabilities.
+** Eldoc
Eldoc presents documentation to the user upon placing ones cursor upon
any symbol. This is very useful when programming as it:
- presents the arguments of functions while writing calls for them
@@ -2292,10 +2298,17 @@ in the minibuffer. A lot cleaner.
(setq eldoc-box-position-function #'eldoc-box--default-upper-corner-position-function
eldoc-box-clear-with-C-g t))
#+end_src
-*** Eglot
-Eglot is a library of packages to communicate with LSP servers for
-better programming capabilities. Interactions with a server provide
-results to the client, done through JSON.
+** Eglot
+Eglot is package to communicate with LSP servers for better
+programming capabilities. Interactions with a server provide results
+to the client, done through JSON.
+
+NOTE: Emacs 28.1 comes with better JSON parsing, which makes Eglot
+much faster.
+
+2023-03-26: I've found Eglot to be useful sometimes, but many of the
+projects I work on don't require a heavy server setup to efficiently
+edit and check for errors; Emacs provides a lot of functionality.
#+begin_src emacs-lisp
(use-package eglot
:after project
@@ -2310,10 +2323,9 @@ results to the client, done through JSON.
;; :init
;; (setq eglot-stay-out-of '(flymake))
:config
- (add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd"))
- (add-to-list 'eglot-server-programs `(csharp-mode "~/.local/src/omnisharp-roslyn/run" "-lsp")))
+ (add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd")))
#+end_src
-*** Flycheck
+** Flycheck
Flycheck is the checking system for Emacs. I don't necessarily like
having all my code checked all the time, so I haven't added a hook to
prog-mode as it would be better for me to decide when I want checking
@@ -2337,7 +2349,7 @@ and when I don't.
(with-eval-after-load "evil-collection"
(evil-collection-flycheck-setup)))
#+end_src
-*** Tabs and spaces
+** Tabs and spaces
By default, turn off tabs and set the tab width to two.
#+begin_src emacs-lisp
(setq-default indent-tabs-mode nil
@@ -2350,11 +2362,11 @@ However, if necessary later, define a function that may activate tabs locally.
(interactive)
(setq-local indent-tabs-mode t))
#+end_src
-*** Highlight todo items
-TODO items are highlighted in org buffers, but not necessarily in
-every buffer. This minor mode highlights all TODO like items via a
-list of strings to match. It also configures faces to use when
-highlighting.
+** Highlight todo items
+TODO items are highlighted in org-mode, but not necessarily in every
+mode. This minor mode highlights all TODO like items via a list of
+strings to match. It also configures faces to use when highlighting.
+I hook it to prog-mode.
#+begin_src emacs-lisp
(use-package hl-todo
@@ -2364,20 +2376,20 @@ highlighting.
(setq hl-todo-keyword-faces
'(("TODO" . "#E50000")
("WAIT" . "#00CC00")
- ("FIXME" . "#d02090")))
- )
+ ("FIXME" . "#d02090"))))
#+end_src
-*** Hide-show mode
-Turn on ~hs-minor-mode~ for all prog-mode.
+** Hide-show mode
+Turn on ~hs-minor-mode~ for all prog-mode. This provides folds for
+free.
#+begin_src emacs-lisp
(use-package hideshow
:straight nil
:hook (prog-mode-hook . hs-minor-mode))
#+end_src
-*** Aggressive indenting
-Essentially my dream editing experience, when I type stuff in try and
-indent it for me on the fly. Just checkout the [[https://github.com/Malabarba/aggressive-indent-mode][page]], any way I
-describe it won't do it justice.
+** Aggressive indenting
+Essentially my dream editing experience: when I type stuff in, try and
+indent it for me on the fly. Just checkout the [[https://github.com/Malabarba/aggressive-indent-mode][page]], any description
+I give won't do it justice.
#+begin_src emacs-lisp
(use-package aggressive-indent
@@ -2386,11 +2398,13 @@ describe it won't do it justice.
:hook
(prog-mode-hook . aggressive-indent-mode))
#+end_src
+* Languages
+Configuration for specific languages or file formats.
** PDF
-I use PDFs mostly for reading reports or papers, providing great
-formatting options. Though Emacs isn't my favourite application for
-viewing PDFs (I highly recommend [[https://pwmt.org/projects/zathura/][Zathura]]), similar to most things with
-Emacs, having a PDF viewer builtin can be a very useful asset.
+I use PDFs mostly for reading reports or papers. Though Emacs isn't
+my preferred application for viewing PDFs (I highly recommend
+[[https://pwmt.org/projects/zathura/][Zathura]]), similar to most things with Emacs, having a PDF viewer
+builtin can be a very useful asset.
For example if I were editing an org document which I was eventually
compiling into a PDF, my workflow would be much smoother with a PDF
@@ -2414,8 +2428,10 @@ There is no proper PDF viewing without this package.
(evil-collection-pdf-setup)))
#+end_src
*** PDF grep
-PDF grep is a Linux tool that allows for searches against PDFs similar
-to standard grep (but for PDFs!).
+PDF grep is a Linux tool that allows for searches against the text
+inside of PDFs similar to standard grep. This cannot be performed by
+standard grep due to how PDFs are encoded; they are not a clear text
+format.
#+begin_src emacs-lisp
(use-package pdfgrep
:after pdf-tools
@@ -2426,8 +2442,10 @@ to standard grep (but for PDFs!).
"M-g" #'pdfgrep))
#+end_src
** SQL
-SQL package, with support for connecting to common database types
-(sqlite, mysql, etc) for auto completion and query execution.
+The default SQL package provides support for connecting to common
+database types (sqlite, mysql, etc) for auto completion and query
+execution. I don't use SQL currently but whenever I need it it's
+there.
#+begin_src emacs-lisp
(use-package sql
:straight nil
@@ -2438,9 +2456,9 @@ SQL package, with support for connecting to common database types
:PROPERTIES:
:header-args:emacs-lisp: :tangle no
:END:
-Check out [[file:elisp/ada-mode.el][ada-mode*]], my custom ~ada-mode~ that replaces the default one.
-This mode just colourises stuff, and uses eglot to do the important
-stuff.
+Check out [[file:elisp/ada-mode.el][ada-mode]], my custom ~ada-mode~ that replaces the default
+one. This mode just colourises stuff, and uses eglot and a language
+server to do the hard work.
#+begin_src emacs-lisp
(use-package ada-mode
@@ -2464,6 +2482,7 @@ the [[https://elpa.gnu.org/packages/nhexl-mode.html][page]] yourself.
:mode "\\.bin")
#+end_src
** Org
+Org mode
*** Org Core Variables
Tons of variables for org-mode, including a ton of latex ones. Can't
really explain because it sets up quite a lot of local stuff. Also I