diff options
Diffstat (limited to 'Emacs/.config/emacs/config.org')
-rw-r--r-- | Emacs/.config/emacs/config.org | 1534 |
1 files changed, 21 insertions, 1513 deletions
diff --git a/Emacs/.config/emacs/config.org b/Emacs/.config/emacs/config.org index 7e09fba..d2116e3 100644 --- a/Emacs/.config/emacs/config.org +++ b/Emacs/.config/emacs/config.org @@ -389,748 +389,12 @@ Eww who uses a mouse? #+begin_src emacs-lisp (setq use-file-dialog nil) #+end_src -* 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 general - :demand t - :config - ;; General which key definitions for leaders - (general-def - :states '(normal motion) - "SPC" 'nil - "\\" '(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 "\\") - - (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") - ";" '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")) - - (mode-leader - "t" #'+oreo/switch-theme) - - (code-leader - "F" `(,(proc (interactive) (find-file "~/Code/")) - :which-key "Open ~/Code/")) - - (file-leader - "f" #'find-file - "F" #'find-file-other-frame - "s" #'save-buffer - "p" `(,(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 - "zO" #'hs-show-all - "'" #'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-SPC" #'ivy-occur) - (general-def - :keymaps 'ivy-switch-buffer-map - "M-j" #'ivy-next-line-or-history - "M-k" #'ivy-previous-line-or-history) - (nmap - :keymaps '(ivy-occur-mode-map ivy-occur-grep-mode-map) - "RET" #'ivy-occur-press-and-switch - "J" #'ivy-occur-press - "gr" #'ivy-occur-revert-buffer - "q" #'quit-window - "D" #'ivy-occur-delete-candidate - "W" #'ivy-wgrep-change-to-wgrep-mode - "{" #'compilation-previous-file - "}" #'compilation-next-file) - :init - (with-eval-after-load "evil" - (evil-set-initial-state 'ivy-occur-mode 'normal) - (evil-set-initial-state 'ivy-occur-grep-mode 'normal)) - (with-eval-after-load "amx" - (setq amx-backend 'ivy)) - - (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) - :config - (require 'counsel nil t)) -#+end_src -**** Counsel -Setup for counsel. Load after ivy and helpful. -#+begin_src emacs-lisp -(use-package counsel - :defer t - :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 '((org-insert-link . "^")) - 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 -**** WIP Ivy posframe -:PROPERTIES: -:header-args:emacs-lisp: :tangle no -:END: -This makes ivy minibuffer windows use child frames. -Very nice eyecandy, but can get kinda annoying. -#+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 -**** WIP 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 -*** WIP 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) - (mapcar - #'(lambda (arg) - (let ((mode (car arg)) - (rest (cdr arg))) - `(add-hook - ',mode - #'(lambda nil - (setq prettify-symbols-alist ',rest) - (prettify-symbols-mode))))) - args))))) -#+end_src - -Here's a collection of keywords and possible associated symbols for -any prog language of choice. Mostly for reference and copying. -#+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 on -a whim 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. - -I have no idea whether it's optimal AT ALL, but it works for me. -#+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) - (mapcar - #'(lambda (arg) - `(add-to-list 'display-buffer-alist - ',arg)) - args))))) -#+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 - ("\\*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 +abbrev/define-abbrevs (abbrev-table &rest abbrevs) - `(progn - ,@(mapcar #'(lambda (abbrev) - `(define-abbrev - ,abbrev-table - ,(car abbrev) - "" - (proc (insert ,(cadr abbrev))))) - abbrevs))) - (setq save-abbrevs nil) - :config - (+abbrev/define-abbrevs - global-abbrev-table - ("sdate" - (format-time-string "%Y-%m-%d" (current-time))) - ("stime" - (format-time-string "%H:%M:%S" (current-time))) - ("sday" - (format-time-string "%A" (current-time))) - ("smon" - (format-time-string "%B" (current-time))))) -#+end_src -*** WIP Skeletons -:PROPERTIES: -:header-args:emacs-lisp: :tangle no -:END: -Defines a macro for generating a skeleton + abbrev for a given mode. -Doesn't sanitise inputs because I assume callers are /rational/ actors -who would *only* use this for their top level Emacs config. - -Honestly didn't find much use for this currently, so disabled. +* Core packages (loading) +For my core packages, whose configuration doesn't change much anyway, +I have a [[file:core.org][separate file]]. Here I'll load it up for +usage later on. #+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 immediately upon creating a new buffer with a -given name. Supports skeletons for inserting text. To make it easier -for later systems to define their own auto inserts, I define a -~use-package~ keyword ~auto-insert~ which allows one to define an -entry for ~auto-insert-alist~. -#+begin_src emacs-lisp -(use-package autoinsert - :straight nil - :demand t - :hook (after-init-hook . auto-insert-mode) - :config - (with-eval-after-load "use-package-core" - (add-to-list 'use-package-keywords ':auto-insert) - (defun use-package-normalize/:auto-insert (_name-symbol _keyword args) - args) - (defun use-package-handler/:auto-insert (name _keyword args rest state) - (use-package-concat - (use-package-process-keywords name rest state) - (mapcar - #'(lambda (arg) - `(add-to-list - 'auto-insert-alist - ',arg)) - 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 - :defer t - :hook - (prog-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 -** Licensing -Loads [[file:elisp/license.el][license.el]] for inserting licenses. -Licenses are important for distribution and attribution to be defined clearly. -#+begin_src emacs-lisp -(use-package license - :straight nil - :load-path "elisp/" - :demand t - :general - (insert-leader - "l" #'+license/insert-copyright-notice - "L" #'+license/insert-complete-license)) +(load-file (concat user-emacs-directory "core.el")) #+end_src * Small packages ** ISearch @@ -1460,784 +724,28 @@ text. That's what this is mainly for. (mode-leader "r" #'toggle-rot13-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. -** WIP Dashboard -:PROPERTIES: -:header-args:emacs-lisp: :tangle no -:END: -Dashboard creates a custom dashboard for Emacs that replaces the -initial startup screen in default Emacs. It has a lot of customising -options. - -Unfortunately not that useful, many things are easier to invoke -directly such as recent files or project changing. -#+begin_src emacs-lisp -(use-package dashboard - :straight t - :demand t - :general - (app-leader - "b" #'dashboard-refresh-buffer) - (:states '(normal motion emacs) - :keymaps 'dashboard-mode-map - "q" (proc (interactive) (kill-this-buffer))) - (nmmap - :keymaps 'dashboard-mode-map - "r" #'dashboard-jump-to-recent-files - "p" #'dashboard-jump-to-projects - "}" #'dashboard-next-section - "{" #'dashboard-previous-section) - :init - (setq initial-buffer-choice nil - dashboard-banner-logo-title "Oreomacs" - dashboard-center-content t - dashboard-set-init-info t - dashboard-startup-banner (no-littering-expand-etc-file-name "dashboard/logo.png") - dashboard-set-footer t - dashboard-set-navigator t - dashboard-items '((projects . 5) - (recents . 5)) - dashboard-footer-messages (list - "Collecting parentheses..." - "Linking 'coffee_machine.o'..." - "Uploading ip to hacker named 4chan..." - "Dividing by zero..." - "Solving 3-sat..." - "Obtaining your health record..." - (format "Recompiling Emacs for the %dth time..." (random 1000)) - "Escaping the cycle of samsara...")) - :config - (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 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 - :defer t - :commands (+calendar/copy-date +calendar/toggle-calendar) - :display - ("\\*Calendar\\*" - (display-buffer-at-bottom) - (inhibit-duplicate-buffer . t) - (window-height . 0.17)) - :general - (nmmap - :keymaps 'calendar-mode-map - "Y" #'+calendar/copy-date) - (app-leader - "d" #'+calendar/toggle-calendar) - :config - (defun +calendar/copy-date () - "Copy date under cursor into kill ring." - (interactive) - (if (use-region-p) - (call-interactively #'kill-ring-save) - (let ((date (calendar-cursor-to-date))) - (when date - (setq date (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date))) - (kill-new (format-time-string "%Y-%m-%d" date)))))) - (+oreo/create-toggle-function - +calendar/toggle-calendar - "*Calendar*" - calendar - nil)) -#+end_src -** Mail -Mail is a funny thing; most people use it just for business or -advertising and it's come out of use in terms of personal -communication in the west for the most part (largely due to "social" -media applications). However, this isn't true for the open source and -free software movement who heavily use mail for communication. - -Integrating mail into Emacs helps as I can send source code and -integrate it into my workflow just a bit better. -*** Notmuch -#+begin_src emacs-lisp -(use-package notmuch - :defer t - :commands (notmuch +mail/flag-thread) - :general - (app-leader "m" #'notmuch) - (nmap - :keymaps 'notmuch-search-mode-map - "f" #'+mail/flag-thread) - :init - (defconst +mail/signature "---------------\nAryadev Chavali") - (defconst +mail/local-dir (concat user-emacs-directory ".mail/")) - (setq notmuch-show-logo nil - notmuch-search-oldest-first nil - notmuch-hello-sections '(notmuch-hello-insert-saved-searches - notmuch-hello-insert-alltags - notmuch-hello-insert-recent-searches) - notmuch-archive-tags '("-inbox" "-unread" "+archive") - mail-signature +mail/signature - mail-default-directory +mail/local-dir - mail-source-directory +mail/local-dir - message-signature +mail/signature - message-auto-save-directory +mail/local-dir - message-directory +mail/local-dir) - - (defun +mail/sync-mail () - "Sync mail via mbsync." - (interactive) - (start-process-shell-command "" nil "mbsync -a")) - (defun +mail/trash-junk () - "Delete any mail in junk" - (interactive) - (start-process-shell-command "" nil "notmuch search --output=files --format=text0 tag:deleted tag:spam tag:trash tag:junk | xargs -r0 rm")) - :config - (defun +mail/flag-thread (&optional unflag beg end) - (interactive (cons current-prefix-arg (notmuch-interactive-region))) - (notmuch-search-tag - (notmuch-tag-change-list '("-inbox" "+flagged") unflag) beg end) - (when (eq beg end) - (notmuch-search-next-thread))) - (advice-add #'notmuch-poll-and-refresh-this-buffer :before -#'+mail/sync-mail) - (advice-add #'notmuch-poll-and-refresh-this-buffer :after -#'+mail/trash-junk) - (with-eval-after-load "evil-collection" - (evil-collection-notmuch-setup))) -#+end_src -*** Smtpmail -#+begin_src emacs-lisp -(use-package smtpmail - :after notmuch - :commands mail-send - :custom - (smtpmail-smtp-server "mail.aryadevchavali.com") - (smtpmail-smtp-user "aryadev") - (smtpmail-smtp-service 587) - (smtpmail-stream-type 'starttls) - :init - (setq send-mail-function #'smtpmail-send-it - message-send-mail-function #'smtpmail-send-it)) -#+end_src -** Dired -Setup for dired. Make dired-hide-details-mode the default mode when -using dired-mode, as it removes the clutter. Setup evil collection -for dired (even though dired doesn't really conflict with evil, there -are some corners I'd like to adjust). -#+begin_src emacs-lisp -(use-package dired - :straight nil - :commands (dired find-dired) - :hook - (dired-mode-hook . auto-revert-mode) - (dired-mode-hook . dired-hide-details-mode) - :init - (setq-default dired-listing-switches "-AFBl --group-directories-first" - dired-omit-files "^\\." - dired-dwim-target t) - (with-eval-after-load "evil-collection" - (evil-collection-dired-setup)) - :general - (nmmap - :keymaps 'dired-mode-map - "T" #'dired-create-empty-file - "H" #'dired-up-directory - "L" #'dired-find-file) - (dir-leader - "f" #'find-dired - "d" #'dired - "D" #'dired-other-frame - "i" #'image-dired - "p" `((proc (interactive) - (dired "~/Text/PDFs/")) - :which-key "Open PDFs")) - :config - (defun +dired/insert-all-subdirectories () - "Insert all subdirectories currently viewable." - (interactive) - (dired-mark-directories nil) - (dolist #'dired-insert-subdir (dired-get-marked-files)) - (dired-unmark-all-marks)) - - (nmmap - :keymaps 'dired-mode-map - "SPC" nil - "SPC ," nil) - - (nmmap - :keymaps 'image-dired-thumbnail-mode-map - "h" #'image-dired-backward-image - "l" #'image-dired-forward-image - "j" #'image-dired-next-line - "k" #'image-dired-previous-line - "H" #'image-dired-display-previous - "L" #'image-dired-display-next - "RET" #'image-dired-display-this - "m" #'image-dired-mark-thumb-original-file - "q" #'quit-window) - - (local-leader - :keymaps 'dired-mode-map - "l" #'dired-maybe-insert-subdir - "m" #'dired-mark-files-regexp - "u" #'dired-undo)) -#+end_src - -*** fd-dired -Uses fd for finding file results in a directory: ~find-dired~ -> -~fd-dired~. - -#+begin_src emacs-lisp -(use-package fd-dired - :after dired - :straight t - :general - (dir-leader - "g" #'fd-dired)) -#+end_src -** Xwidget -Xwidget is a package which allows for the insertion of arbitrary -xwidgets into Emacs through buffers. It must be compiled into Emacs -so you might need to customise your install. One of its premier uses -is in navigating the web which it provides through the function -~xwidget-webkit-browse-url~. This renders a fully functional web -browser within Emacs. - -Though I am not to keen on using Emacs to browse the web /via/ xwidget -(EWW does a good job on its own), I am very interested in its -capability to render pages with JavaScript, as it may come of use when -doing web development. I can see the results of work very quickly -without switching windows all within Emacs. -*** Xwidget Core -#+begin_src emacs-lisp -(use-package xwidget - :straight nil - :general - (app-leader - "u" #'xwidget-webkit-browse-url) - (nmmap - :keymaps 'xwidget-webkit-mode-map - "q" #'quit-window - "h" #'xwidget-webkit-scroll-backward - "j" #'xwidget-webkit-scroll-up - "k" #'xwidget-webkit-scroll-down - "l" #'xwidget-webkit-scroll-forward - "+" #'xwidget-webkit-zoom-in - "-" #'xwidget-webkit-zoom-out - (kbd "C-f") #'xwidget-webkit-scroll-up - (kbd "C-b") #'xwidget-webkit-scroll-down - "H" #'xwidget-webkit-back - "L" #'xwidget-webkit-forward - "gu" #'xwidget-webkit-browse-url - "gr" #'xwidget-webkit-reload - "gg" #'xwidget-webkit-scroll-top - "G" #'xwidget-webkit-scroll-bottom)) -#+end_src -*** Xwidget Extensions -Define a function ~+xwidget/render-file~ that reads a file name and -presents it in an xwidget. If the current file is an HTML file, ask -if user wants to open current file. Bind it to ~aU~ in the leader. - -Also define a function ~+xwidget/search-query~ that first asks the -user what search engine they want to use ([[https://duckduckgo.com][Duck Duck Go]] and [[https://devdocs.io][DevDocs]] -currently) then asks for a query, which it parses then presents in an -xwidget window. Bind to ~as~ in the leader. -#+begin_src emacs-lisp -(use-package xwidget - :straight nil - :commands (+xwidget/render-file +xwidget/search) - :general - (app-leader - "U" #'+xwidget/render-file - "s" #'+xwidget/search) - :config - (setenv "WEBKIT_FORCE_SANDBOX" "0") - (defun +xwidget/render-file (&optional FORCE) - "Find file (or use current file) and render in xwidget." - (interactive) - (cond - ((and (not FORCE) (or (string= (replace-regexp-in-string ".*.html" - "html" (buffer-name)) "html") - (eq major-mode 'web-mode) - (eq major-mode 'html-mode))) ; If in html file - (if (y-or-n-p "Open current file?: ") ; Maybe they want to open a separate file - (xwidget-webkit-browse-url (format "file://%s" (buffer-file-name))) - (+xwidget/render-file t))) ; recurse and open file via prompt - (t - (xwidget-webkit-browse-url - (format "file://%s" (read-file-name "Enter file to open: ")))))) - - (defun +xwidget/search () - "Run a search query on some search engine and display in -xwidget." - (interactive) - (let* ((engine (completing-read "Engine: " '("duckduckgo.com" "devdocs.io") nil t)) - (query-raw (read-string "Enter query: ")) - (query - (cond - ((string= engine "duckduckgo.com") query-raw) - ((string= engine "devdocs.io") (concat "_ " query-raw))))) - (xwidget-webkit-browse-url (concat "https://" engine "/?q=" query))))) -#+end_src -** Eshell -*** Why Eshell? -Eshell is an integrated shell environment for Emacs, written in Emacs -Lisp. I argue that it is the best shell/command interpreter to use in -Emacs. - -Eshell is unlike the alternatives in Emacs as it's a /shell/ first, -not a terminal emulator. It has the ability to spoof some aspects of a -terminal emulator (through the shell parser), but it is NOT a terminal -emulator. - -The killer benefits of eshell (which would appeal to Emacs users) are -a direct result of eshell being written in Emacs lisp: -- incredible integration with Emacs utilities (such as ~dired~, - ~find-file~, any read functions, to name a few) -- very extensible, easy to write new commands which leverage Emacs - commands as well as external utilities -- agnostic of platform: "eshell/cd" will call the underlying change - directory function for you, so commands will (usually) mean the same - thing regardless of platform - - this means as long as Emacs runs, you can run eshell - -However, my favourite feature of eshell is the set of evaluators that -run on command input. Some of the benefits listed above come as a -result of this powerful feature. These evaluators are described below. - -Lisp evaluator: works on braced expressions, evaluating them as Lisp -expressions (e.g. ~(message "Hello, World!\n")~). Any returned -objects are printed. This makes eshell a LISP REPL! - -External evaluator: works within curly braces, evaluating them via -some external shell process (like sh) (e.g. ~{echo "Hello, -world!\n"}~). This makes eshell a (kinda dumb) terminal emulator! - -The alias evaluator is the top level evaluator. It is the main -evaluator for each expression given to eshell. When given an -expression it tries to evaluate it by testing against these conditions: -- it's an alias defined by the user or in the ~eshell/~ namespace of - functions (simplest evaluator) -- it's some form of lisp expression (lisp evaluator) -- it's an external command (bash evaluator) -Essentially, you get the best of both Emacs and external shell -programs *ALL WITHIN* Emacs for free. -*** Eshell functionality -Bind some evil-like movements for easy shell usage, and a toggle -function to pull up the eshell quickly. -#+begin_src emacs-lisp -(use-package eshell - :commands +shell/toggle-eshell - :general - (shell-leader - "t" #'+shell/toggle-eshell) - :init - (add-hook - 'eshell-mode-hook - (proc - (interactive) - (general-def - :states '(normal insert) - :keymaps 'eshell-mode-map - "M-l" (proc (interactive) (eshell/clear) - "M-j" #'eshell-next-matching-input-from-input - "M-k" #'eshell-previous-matching-input-from-input) - (local-leader - :keymaps 'eshell-mode-map - "c" (proc (interactive) (eshell/clear) - (recenter)) - "k" #'eshell-kill-process)))) - :config - (+oreo/create-toggle-function - +shell/toggle-eshell - "*eshell*" - eshell - t)) -#+end_src -*** Eshell pretty symbols and display -Pretty symbols and a display record. -#+begin_src emacs-lisp -(use-package eshell - :defer t - :pretty - (eshell-mode-hook - ("lambda" . "λ") - ("numberp" . "ℤ") - ("t" . "⊨") - ("nil" . "Ø")) - :display - ("\\*e?shell\\*" ; for general shells as well - (display-buffer-at-bottom) - (window-height . 0.25))) -#+end_src -*** Eshell variables and aliases -Set some sane defaults, a banner and a prompt. The prompt checks for -a git repo in the current directory and provides some extra -information in that case (in particular, branch name and if there any -changes that haven't been committed). - -Also add ~eshell/goto~, which is actually a command accessible from -within eshell (this is because ~eshell/*~ creates an accessible -function within eshell with name ~*~). ~eshell/goto~ makes it easier -to change directories by using Emacs' find-file interface (which is -much faster than ~cd ..; ls -l~). -#+begin_src emacs-lisp -(use-package eshell - :config - (defun +eshell/get-git-properties () - (let* ((git-branch (shell-command-to-string "git branch")) - (is-repo (string= (if (string= git-branch "") "" - (substring git-branch 0 1)) "*"))) - (if (not is-repo) "" - (concat - "(" - (nth 2 (split-string git-branch "\n\\|\\*\\| ")) - "<" - (if (string= "" (shell-command-to-string "git status | grep 'up to date'")) - "×" - "✓") - ">)")))) - (setq eshell-cmpl-ignore-case t - eshell-cd-on-directory t - eshell-banner-message (concat (shell-command-to-string "figlet eshell") "\n") - eshell-prompt-function - (proc - (let ((properties (+eshell/get-git-properties))) - (concat - properties - (format "[%s]\n" (abbreviate-file-name (eshell/pwd))) - "λ "))) - eshell-prompt-regexp "^λ ") - - (defun eshell/goto (&rest args) - "Use `read-directory-name' to change directories." - (eshell/cd (list (read-directory-name "Enter directory to go to:"))))) -#+end_src -*** Eshell change directory quickly -~eshell/goto~ is a better ~cd~ for eshell. However it is really just -a plaster over a bigger issue for my workflow; many times I want -eshell to be present in the current directory of the buffer I am -using. - -#+begin_src emacs-lisp -(use-package eshell - :straight nil - :general - (shell-leader - "T" #'+eshell/current-buffer) - :config - (defun +eshell/current-buffer () - (interactive) - (let ((dir (if buffer-file-name - (file-name-directory buffer-file-name) - (if default-directory - default-directory - nil))) - (buf (eshell))) - (if dir - (with-current-buffer buf - (eshell/cd dir) - (eshell-send-input)) - (message "Could not switch eshell: buffer is not real file"))))) -#+end_src -** Elfeed -Elfeed is the perfect RSS feed reader, integrated into Emacs -perfectly. I've got a set of feeds that I use for a large variety of -stuff, mostly media and entertainment. I've also bound "<leader> ar" -to elfeed for loading the system. -#+begin_src emacs-lisp -(use-package elfeed - :general - (app-leader "r" #'elfeed) - (nmmap - :keymaps 'elfeed-search-mode-map - "gr" #'elfeed-update - "s" #'elfeed-search-live-filter - "<return>" #'elfeed-search-show-entry) - :init - (setq elfeed-db-directory (no-littering-expand-var-file-name "elfeed/")) - (setq +rss/feed-urls - '(("Arch Linux" - "https://www.archlinux.org/feeds/news/" - Linux) - ("LEMMiNO" - "https://www.youtube.com/feeds/videos.xml?channel_id=UCRcgy6GzDeccI7dkbbBna3Q" - YouTube Stories) - ("The Onion" - "https://www.theonion.com/rss" - Social) - ("Stack exchange" - "http://morss.aryadevchavali.com/stackexchange.com/feeds/questions" - Social) - ("Dark Sominium" - "https://www.youtube.com/feeds/videos.xml?channel_id=UC_e39rWdkQqo5-LbiLiU10g" - YouTube Stories) - ("Dark Sominium Music" - "https://www.youtube.com/feeds/videos.xml?channel_id=UCkLiZ_zLynyNd5fd62hg1Kw" - YouTube Music) - ("Nexpo" - "https://www.youtube.com/feeds/videos.xml?channel_id=UCpFFItkfZz1qz5PpHpqzYBw" - YouTube) - ("Techquickie" - "https://www.youtube.com/feeds/videos.xml?channel_id=UC0vBXGSyV14uvJ4hECDOl0Q" - YouTube) - ("3B1B" - "https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw" - YouTube) - ("Fredrik Knusden" - "https://www.youtube.com/feeds/videos.xml?channel_id=UCbWcXB0PoqOsAvAdfzWMf0w" - YouTube Stories) - ("Barely Sociable" - "https://www.youtube.com/feeds/videos.xml?channel_id=UC9PIn6-XuRKZ5HmYeu46AIw" - YouTube Stories) - ("Atrocity Guide" - "https://www.youtube.com/feeds/videos.xml?channel_id=UCn8OYopT9e8tng-CGEWzfmw" - YouTube Stories) - ("Hacker News" - "http://morss.aryadevchavali.com/news.ycombinator.com/rss" - Social) - ("Hacker Factor" - "https://www.hackerfactor.com/blog/index.php?/feeds/index.rss2" - Social) - ("BBC Top News" - "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/rss.xml" - News) - ("BBC Tech News" - "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/technology/rss.xml" - News))) - :config - (with-eval-after-load "evil-collection" - (evil-collection-elfeed-setup)) - (setq elfeed-feeds (cl-map 'list #'(lambda (item) - (append (list (nth 1 item)) (cdr (cdr item)))) - +rss/feed-urls))) -#+end_src -** Magit -Magit is *the* git porcelain for Emacs, which perfectly encapsulates -the git cli. In this case I just need to setup the bindings for it. -As magit will definitely load after evil (as it must be run by a -binding, and evil will load after init), I can use evil-collection -freely. Also, define an auto insert for commit messages so that I -don't need to write everything myself. - -#+begin_src emacs-lisp -(use-package magit - :defer t - :display - ("magit:.*" - (display-buffer-same-window) - (inhibit-duplicate-buffer . t)) - ("magit-diff:.*" - (display-buffer-below-selected)) - ("magit-log:.*" - (display-buffer-same-window)) - :general - (leader - "g" '(magit-dispatch :which-key "Magit") - "vf" '(magit-file-dispatch :which-key "Magit file") - "vb" '(magit-blame :which-key "Magit blame")) - (code-leader - "b" #'magit-blame) - :auto-insert - (("COMMIT_EDITMSG" . "Commit skeleton") - "" - "(" (read-string "Enter feature/module: ") ")" - (read-string "Enter simple description: ") "\n\n") - :init - (setq vc-follow-symlinks t - magit-blame-echo-style 'lines) - :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 -** IBuffer -#+begin_src emacs-lisp -(use-package ibuffer - :general - (buffer-leader - "i" #'ibuffer) - :config - (with-eval-after-load "evil-collection" - (evil-collection-ibuffer-setup))) -#+end_src -** Processes -Emacs has two systems for process management: -+ proced: a general 'top' like interface which allows general - management of linux processes -+ list-processes: a specific Emacs based system that lists processes - spawned by Emacs (similar to a top for Emacs specifically) - -*** Proced -Core proced config, just a few bindings and evil collection setup. -#+begin_src emacs-lisp -(use-package proced - :straight nil - :general - (app-leader - "p" #'proced) - (nmap - :keymaps 'proced-mode-map - "za" #'proced-toggle-auto-update) - :display - ("\\*Proced\\*" - (display-buffer-at-bottom) - (window-height . 0.25)) - :init - (setq proced-auto-update-interval 0.5) - :config - (with-eval-after-load "evil-collection" - (evil-collection-proced-setup))) -#+end_src - -Along with that I setup the package ~proced-narrow~ which allows -further filtering of the process list. -#+begin_src emacs-lisp -(use-package proced-narrow - :straight t - :after proced - :general - (nmap - :keymaps 'proced-mode-map - "%" #'proced-narrow)) -#+end_src -** Calculator -Surprise, surprise Emacs comes with a calculator. - -Greater surprise, this thing is over powered. It can perform the -following (and more): -- Matrix calculations -- Generalised calculus operations -- Equation solvers for n-degree multi-variable polynomials -- Embedded mode (check below)! - -~calc-mode~ is a calculator system within Emacs that provides a -diverse array of mathematical operations. It uses reverse polish -notation to do calculations (though there is a standard infix -algebraic notation mode). - -Embedded mode allows computation with the current buffer as the echo -area. This basically means I can compute stuff within a buffer -without invoking calc directly: $1 + 2\rightarrow_{\text{calc-embed}} 3$. - +** Licensing +Loads [[file:elisp/license.el][license.el]] for inserting licenses. +Licenses are important for distribution and attribution to be defined clearly. #+begin_src emacs-lisp -(use-package calc +(use-package license :straight nil - :display - ("*Calculator*" - (display-buffer-at-bottom) - (window-height . 0.18)) - :general - (app-leader - "c" #'calc-dispatch) - (mode-leader - "c" #'calc-embedded) - :init - (setq calc-algebraic-mode t) - :config - (with-eval-after-load "evil-collection" - (evil-collection-calc-setup))) -#+end_src -*** WIP Calctex -:PROPERTIES: -:header-args:emacs-lisp: :tangle no -:END: -~calc-mode~ also has a 3rd party package called ~calctex~. It renders -mathematical expressions within calc as if they were rendered in TeX. -You can also copy the expressions in their TeX forms, which is pretty -useful when writing a paper. I've set a very specific lock on this -repository as it's got quite a messy work-tree and this commit seems to -work for me given the various TeX utilities installed via Arch. - -#+begin_src emacs-lisp -(use-package calctex - :after calc - :straight (calctex :type git :host github :repo "johnbcoughlin/calctex") - :hook (calc-mode-hook . calctex-mode)) -#+end_src -** Ledger -#+begin_src emacs-lisp -(use-package ledger-mode - :defer t) - -(use-package evil-ledger - :after ledger-mode) -#+end_src -** WIP Zone -:PROPERTIES: -:header-args:emacs-lisp: :tangle no -:END: -Of course Emacs has a cool screensaver software. - -#+begin_src emacs-lisp -(use-package zone-matrix - :straight t - :after dashboard - :init - (setq zone-programs - [zone-pgm-jitter - zone-pgm-putz-with-case - zone-pgm-dissolve - zone-pgm-whack-chars - zone-pgm-drip - zone-pgm-rat-race - zone-pgm-random-life - zone-matrix - ]) - :config - (zone-when-idle 15)) -#+end_src -** (Wo)man -Man pages are the user manuals for most software on Linux. Really -useful when writing code for Un*x systems, though they can be very -verbose. - -2023-08-17: `Man-notify-method' is the reason the `:display' record -doesn't work here. I think it's to do with how Man pages are rendered -or something, but very annoying as it's a break from standards! -#+begin_src emacs-lisp -(use-package man + :load-path "elisp/" :demand t - :straight nil - :init - (setq Man-notify-method 'pushy) - :display - ("^\\*Man.*" - (display-buffer-reuse-mode-window display-buffer-same-window)) :general - (file-leader - "m" #'man) ;; kinda like "find man page" - (nmmap - :keymaps 'Man-mode-map - "RET" #'man-follow)) + (insert-leader + "l" #'+license/insert-copyright-notice + "L" #'+license/insert-complete-license)) #+end_src -** gif-screencast -Little application that uses =gifsicle= to make essentially videos of -Emacs. Useful for demonstrating features. +* Applications (loading) +Emacs is basically an operating system whose primary datatype is text. +Applications are interfaces/environments which serve a variety of +purposes, but provide a lot of capability. I have a +[[file:app.org][separate file]] for such configuration (2023-09-29: +mainly because it was so goddamn huge). + #+begin_src emacs-lisp -(use-package gif-screencast - :straight t - :general - (app-leader - "x" #'gif-screencast-start-or-stop) - :init - (setq gif-screencast-output-directory (expand-file-name "~/Media/emacs/"))) +(load-file (concat user-emacs-directory "app.el")) #+end_src * Text modes Standard packages and configurations for text-mode and its derived |