From c337731cdc04d832594e395462e57aef3b8dd8af Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sat, 21 Nov 2020 10:07:18 -0600 Subject: 1.5 bankruptcy --- config.org | 1022 +++++++++++------------------------------------------------- 1 file changed, 181 insertions(+), 841 deletions(-) diff --git a/config.org b/config.org index 493406c..a1bd3e6 100644 --- a/config.org +++ b/config.org @@ -1,20 +1,42 @@ #+TITLE: Emacs config #+AUTHOR: Case Duckworth +# -*- encoding: utf-8-unix -*- #+BABEL: :cache yes #+PROPERTY: header-args :tangle init.el #+OPTIONS: toc:nil -#+BANKRUPTCY_COUNT: 1 +#+BANKRUPTCY_COUNT: 1.5 * Preamble -I wanted to write my Emacs configuration in [[https://orgmode.org][Org mode]] for a while, but never could quite figure out how. Finally, I found [[https://github.com/larstvei/dot-emacs][Lars Tveito]]'s config, which does exactly what I want: =init.el= is small and simple, and replaced after the first run, and =init.org= is automatically tangled. So I'm very excited. +** Inspiration + +I've been inspired by [[https://github.com/larstvei/dot-emacs][Lars Tveito]]'s config, which does exactly what I +want: =init.el= is small and simple, and is replaced after the first +run by the tangled contents of this file -- =config.org= -- which is +furthermore automatically tangled. + +** Problems with this setup + ++ While =config.org= automatically tangles, I can't run =(load-file + init.el)= -- it results in an endless loop for some reason. I might + need to look into a hook of some kind. * License Copyright © 2020 Case Duckworth -This work is free. You can redistribute it and/or modify it under the -terms of the Do What The Fuck You Want To Public License, Version 2, -as published by Sam Hocevar. See the LICENSE file, or below, for more details. + +This work is free. You can redistribute it and/or modify it under the +terms of the Do What the Fuck You Want To Public License, Version 2, +as published by Sam Hocevar. See the LICENSE file, or below, for more +details. + +NOTE: the WTFPL is probably (most definitely!) not compatible with GNU +Emacs's license, and I'm not sure, though I'm pretty confident, that +my =config.org= would be classified as a /derivative work/ under those +terms. Therefore, me licensing my =config.org= under the WTFPL is at +best, unenforceable, and at worst, downright in violation of the GPL. + +SUE ME, RMS !!! #+begin_src text :tangle LICENSE DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE @@ -32,147 +54,187 @@ as published by Sam Hocevar. See the LICENSE file, or below, for more details. 0. You just DO WHAT THE FUCK YOU WANT TO. - #+end_src -Probably that's not legal under the terms of the GPL or whatever Emacs is licensed under. -SUE ME, RMS - * Bootstrap -/Check out Lars's config for the reasoning behind this./ - -When this configuration is loaded for the first time, this ~init.el~ is loaded: +When this configuration is loaded for the first time, /this/ =init.el= +is loaded: -#+BEGIN_SRC emacs-lisp :tangle no - ;; This file replaces itself with the actual configuration when first run. To keep only this version in git, run this command: +#+begin_src emacs-lisp :tangle no + ;; This file replaces itself with the actual configuration when first + ;; run. To keep only this version tracked by git, run the command + ;; ;; git update-index --assume-unchanged init.el ;; - ;; If it needs to be changed, start tracking it again thusly: + ;; If it needs to be changed, start tracking it again with the command + ;; ;; git update-index --no-assume-unchanged init.el - + ;; + ;; edit as needed, and run the first command again. (require 'org) - (find-file (concat user-emacs-directory "init.org")) + (find-file (concat user-emacs-directory "config.org")) (org-babel-tangle) - (load-file (concat user-emacs-directory "early-init.el")) - (load-file (concat user-emacs-directory "init.el")) - (byte-compile-file (concat user-emacs-directory "init.el")) -#+END_SRC + (load-file (concat-user-emacs-directory "early-init.el")) + (load-file (concat-user-emacs-directory "init.el")) +#+end_src ** Tangling -After the first run, the above ~init.el~ will be replaced by the tangled stuff here. However, when /this/ file is edited, we'll need to re-tangle everything. However, nobody has time to do that manually with =C-c C-v t=, /every time/! Luckily, Emacs is highly programmable. + +After first running Emacs with this config, the above snippet will be +replaced by the result of tangling this file. However, when we edit +=config.org=, we'll need to retangle it. The default keybinding to +tangle is =C-c C-v t=, which takes a while and is easy to forget. So +let's automatically tangle =config.org= on save. #+NAME: tangle-on-save -#+BEGIN_SRC emacs-lisp :tangle no +#+begin_src emacs-lisp + ;;; init.el -*- lexical-binding: t; coding: utf-8-unix -*- (defun acdw/tangle-init () - "If the current buffer is `init.org', the code blocks are tangled, - and the tangled file is compiled and loaded." + "If the current buffer is `config.org', the code blocks are + tangled, and the tangled file is compiled and loaded." (interactive) - (when (equal (buffer-file-name) - (expand-file-name - (concat user-emacs-directory "config.org"))) - ;; Now with async! - (require 'async) - (async-start - `(lambda () - ;; Avoid running hooks when tangling. - (let ((prog-mode-hook nil)) - (require 'org) - (org-babel-tangle-file - (expand-file-name - (concat user-emacs-directory "config.org"))))) - (lambda (_) - (message "Tangle complete."))))) - + (let (config-org (expand-file-name + (concat user-emacs-directory "config.org"))) + (when (equal (buffer-file-name) config-org) + (require 'async) + (async-start + `(lambda () + ;; Avoid running hooks when tangling. + (let ((prog-mode-hook nil)) + (require 'org) + (org-babel-tangle-file config-org))) + (lambda (_) + (message "Tangle complete.")))))) + + ;; Add a hook to tangle config.org. (add-hook 'after-save-hook #'acdw/tangle-init) -#+END_SRC +#+end_src * Early initiation -Emacs 27.1+ uses ~early-init.el~, which is evaluated before things like ~package.el~ and other stuff. So I have a few settings in there. -** Preamble -Of course, first thing is the modeline. After that, I set ~load-prefer-newer~ because, well, it /should/. -#+BEGIN_SRC emacs-lisp :tangle early-init.el - ;;; early-init.el -*- lexical-binding: t; no-byte-compile: t -*- - -(setq load-prefer-newer t) -#+END_SRC - -** Computers -I have to set these constants before bootstrapping the package manager, since ~straight.el~ depends on Git, and at work, those are in a weird place. +Emacs 27.1+ uses =early-init.el= /in addition to/ =init.el=, mostly +for settings related to packags. Since I use =straight.el= for +package management, I need to specify that in this file. -#+BEGIN_SRC emacs-lisp :tangle early-init.el - (defconst *acdw/at-work* (eq system-type 'windows-nt)) - (defconst *acdw/at-larry* (string= (system-name) "larry")) - (defconst *acdw/at-bax* (string= (system-name) "bax")) - (defconst *acdw/at-home* (or *acdw/at-larry* *acdw/at-bax*)) -#+END_SRC +#+begin_src emacs-lisp :tangle early-init.el + ;;; early-init.el -*- lexical-binding: t; no-byte-compile: t -*- + ;; DO NOT EDIT THIS FILE BY HAND. Edit =config.org= instead! -** Package management - I've started using straight.el, which is great. It grabs packages from git, and apparently will let me fork and edit them, which I'll probably get around to ... eventually. + (setq load-prefer-newer t) -*** At work, Git's in a weird place -#+BEGIN_SRC emacs-lisp :tangle early-init.el - (when *acdw/at-work* + (when (eq system-type 'windows-nt) ; I'm at work (add-to-list 'exec-path "~/bin") - (add-to-list 'exec-path "C:/Users/aduckworth/Downloads/PortableGit/bin")) -#+END_SRC + (add-to-list 'exec-path + "C:/Users/aduckworth/Downloads/PortableGit/bin")) -*** [[https://github.com/raxod502/straight.el][straight.el]] -I don't know why, but for some reason the bootstrapping doesn't work on Windows. I have to download the repo directly from github and put it in the right place (=~/.emacs.d/straight/repos/straight.el/=). + ;; This DOES NOT WORK on Windows. + ;; Download the repo directly from Github and unzip it into + ;; ~/.emacs.d/straight/repos/straight.el. -#+BEGIN_SRC emacs-lisp :tangle early-init.el (defvar bootstrap-version) (let ((bootstrap-file - (expand-file-name "straight/repos/straight.el/bootstrap.el" - user-emacs-directory)) - (bootstrap-version 5)) + (expand-file-name "straight/repos/straight.el/bootstrap.el" + user-emacs-directory)) + (bootstrap-version 5)) (unless (file-exists-p bootstrap-file) (with-current-buffer - (url-retrieve-synchronously - "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" - 'silent 'inhibit-cookies) - (goto-char (point-max)) - (eval-print-last-sexp))) + (url-retrieve-synchronously + "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) -#+END_SRC -*** [[https://github.com/jwiegley/use-package][use-package]] -Yeah, you know it, I know it, we all love it. It's use-package. -#+BEGIN_SRC emacs-lisp :tangle early-init.el + ;; Use-package + (setq straight-use-package-by-default t) (straight-use-package 'use-package) -#+END_SRC -* Begin init.el -#+BEGIN_SRC emacs-lisp :noweb tangle - ;;; init.el -*- lexical-binding: t; coding: utf-8 -*- - <> -#+END_SRC + + ;; Use-package extra keywords + + (use-package use-package-custom-update + :straight (use-package-custom-update + :host github + :repo "a13/use-package-custom-update")) + +#+end_src + * Macros + ** cuss -I like ~use-package~, but I don't like doing the weird "pseudo-package" stuff a lot of people do in their emacs configs. Partially because I have to set ~:straight nil~ on a lot of built-in packages, but also because I think being /that/ obsessive over one interface through the whole config is ... I don't know, short-sighted? -Either way, I /do/ like the ~:custom~ interface that ~use-package~ has, so I've re-implemented it in my own macro. This way I don't have to worry about whether to ~setq~ or ~custom-set-variable~ or whatever. Just ~cuss~! -#+BEGIN_SRC emacs-lisp +I like =use-package= a lot, but I don't like the weird +"pseudo-package" things you see with a lot of =use-package= setups +around the Internet. They're cludgy, they /don't/ actually, in my +opinion anyway, make the config any easier to read (how am I supposed +to know what options are in =mule=, for example?!), and most +importantly, =straight.el= doesn't really like them that much. + +*However*, I really like the =:custom= keyword in =use-package=, + enough to implement it as my own macro. =cuss= will automagically + call =custom-set-variable= or =setq=, whichever is best for the + variable being tweaked. I pulled this straight from =use-package=, + so I /know/ it works! :P + +#+begin_src emacs-lisp (defmacro cuss (var val) - "Basically `use-package''s `:custom', but without either." + "Basically the `:custom' macro from `use-package', by itself." `(progn (funcall (or (get ',var 'custom-set) #'set-default) - ',var ,val))) -#+END_SRC + ',var ,val))) +;;; test +#+end_src + +* Machines + +I use Emacs on a couple of different computers: my two at home, and +assorted Windows machines at work. I define a couple of constants to +easily keep track of which computer I'm using. + +#+begin_src emacs-lisp + (defconst *acdw/at-work* (eq system-type 'windows-nt)) + + (defconst *acdw/at-larry* (string= (system-name) "larry")) + (defconst *acdw/at-bax* (string= (system-name) "bax")) + (defconst *acdw/at-home* (or *acdw/at-larry* *acdw/at-bax*)) +#+end_src + * Files -** [[https://github.com/emacscollective/no-littering][Keep .emacs.d tidy]] -#+BEGIN_SRC emacs-lisp - (straight-use-package 'no-littering) - (require 'no-littering) -#+END_SRC + +** Keep .emacs.d tidy + + By default, Emacs keeps files all over the damn place. I like the + =no-littering= package to keep files in one of two directories -- + =etc/= and =var/=. I'm going to require it right away so that I can + immediately use it. + + #+begin_src emacs-lisp + (use-package no-littering) + (require 'no-littering) + #+end_src + ** Customize -I don't like the customize interface, but I still sometimes use it when I'm not sure what the name of a variable is. So I save the stuff to a file, I just don't load it or keep track of it. -#+BEGIN_SRC emacs-lisp + +I don't use the customize interface -- but sometimes it's good to +figure out what settings are available for a package. So I keep the +customizations in a file (some people just throw it in =/dev/null=), +but I /don't/ load the file. + +#+begin_src emacs-lisp (cuss custom-file (no-littering-expand-etc-file-name "custom.el")) -#+END_SRC +#+end_src + ** Encoding -#+BEGIN_SRC emacs-lisp + +It's 2020 -- let's use UTF-8 everywhere. Furthermore, even Notepad +can figure out Unix line endings (=LF=) -- so let's only use that. + +I'm going to be perfectly honest here. I'm not sure what like, any of +these do. I just threw everything =utf-8-unix= into a block and hope +for the best. + +#+begin_src emacs-lisp (prefer-coding-system 'utf-8-unix) (set-default-coding-systems 'utf-8-unix) (set-terminal-coding-system 'utf-8-unix) @@ -181,753 +243,31 @@ I don't like the customize interface, but I still sometimes use it when I'm not (set-file-name-coding-system 'utf-8-unix) (set-clipboard-coding-system 'utf-8-unix) (set-buffer-file-coding-system 'utf-8-unix) - (cuss locale-coding-system 'utf-8) + (cuss locale-coding-system 'utf-8-unix) (cuss x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)) -#+END_SRC -** Recent files -#+BEGIN_SRC emacs-lisp - (use-package recentf - :config - (add-to-list 'recentf-exclude no-littering-var-directory) - (add-to-list 'recentf-exclude no-littering-etc-directory) - :custom - (recentf-max-menu-items 100) - (recentf-max-saved-items 100) - :config - (recentf-mode 1)) -#+END_SRC -** Backups -#+BEGIN_SRC emacs-lisp - (cuss backup-directory-alist - `((".*" . ,(no-littering-expand-var-file-name "backup/")))) -#+END_SRC -** [[https://github.com/bbatsov/super-save][Autosave]] -#+BEGIN_SRC emacs-lisp - (use-package super-save - :custom - (auto-save-default nil) - (super-save-exclude '(".gpg")) - :config - (super-save-mode 1)) -#+END_SRC -** [[https://www.emacswiki.org/emacs/SavePlace][Save places]] -#+BEGIN_SRC emacs-lisp - (use-package saveplace - :custom - (save-place-file (no-littering-expand-var-file-name "places")) - (save-place-forget-unreadable-files (not *acdw/at-work*)) - :config - (save-place-mode 1)) -#+END_SRC -** [[https://www.emacswiki.org/emacs/SaveHist][Save history]] -#+BEGIN_SRC emacs-lisp - (use-package savehist - :custom - (savehist-addtional-variables - '(kill-ring - search-ring - regexp-search-ring)) - (savehist-save-minibuffer-history t) - :config - (savehist-mode 1)) -#+END_SRC -* User interface -** Look -*** Frames and windows -**** Frame defaults -#+BEGIN_SRC emacs-lisp - (cuss default-frame-alist '((tool-bar-lines . 0) - (menu-bar-lines . 0) - (vertical-scroll-bars . nil) - (horizontal-scroll-bars . nil) - (right-divider-width . 2) - (bottom-divider-width . 2) - (left-fringe-width . 2) - (right-fringe-width . 2))) - - ;; also disable these with modes, so I can re-enable them more easily - (menu-bar-mode -1) - (tool-bar-mode -1) - (scroll-bar-mode -1) -#+END_SRC -**** Resizing -#+BEGIN_SRC emacs-lisp - (cuss frame-resize-pixelwise t) - (cuss window-combination-resize t) -#+END_SRC -*** Buffers -#+BEGIN_SRC emacs-lisp - (cuss uniquify-buffer-name-style 'forward) - - (cuss indicate-buffer-boundaries - '((top . right) - (bottom . right) - (t . nil))) -#+END_SRC -**** Startup buffer -#+BEGIN_SRC emacs-lisp - (cuss inhibit-startup-buffer-menu t) - (cuss inhibit-startup-screen t) - (cuss initial-buffer-choice t) ; start in *scratch* - (cuss initial-scratch-message nil) -#+END_SRC -*** Cursor -#+BEGIN_SRC emacs-lisp - (cuss cursor-type 'bar) - (cuss cursor-in-non-selected-windows 'hollow) - (blink-cursor-mode 0) -#+END_SRC -*** Interactivity -**** Mouse -#+BEGIN_SRC emacs-lisp - (cuss mouse-yank-at-point t) -#+END_SRC -**** Dialogs -#+BEGIN_SRC emacs-lisp - (cuss use-dialog-box nil) -#+END_SRC -**** Disabled functions -#+BEGIN_SRC emacs-lisp - (cuss disabled-command-function nil) -#+END_SRC -**** Function aliases -#+begin_src emacs-lisp - (fset 'yes-or-no-p #'y-or-n-p) -#+end_src -*** Miscellaneous -**** Convert =^L= to a line -#+begin_src emacs-lisp - (use-package form-feed - :hook - ((text-mode prog-mode) . form-feed-mode)) #+end_src -** Themes: [[https://github.com/protesilaos/modus-themes][Modus]] -#+BEGIN_SRC emacs-lisp - (use-package modus-operandi-theme) - (use-package modus-vivendi-theme) -#+END_SRC -*** [[https://github.com/hadronzoo/theme-changer][Change themes]] based on time of day -#+BEGIN_SRC emacs-lisp - (use-package theme-changer - :init - (setq calendar-location-name "Baton Rouge, LA" - calendar-latitude 30.39 - calendar-longitude -91.83) - :config - (change-theme 'modus-operandi 'modus-vivendi)) -#+END_SRC -*** Disable the current theme when a theme is interactively loaded -This doesn't happen often, but I'll be ready when it does. -#+begin_src emacs-lisp - (defadvice load-theme - (before disable-before-load (theme &optional no-confirm no-enable) activate) - (mapc 'disable-theme custom-enabled-themes)) -#+end_src -** Modeline: [[https://github.com/Malabarba/smart-mode-line][smart-mode-line]] -#+BEGIN_SRC emacs-lisp - (use-package smart-mode-line - :config - (sml/setup)) -#+END_SRC -I hide all minor-modes by default for a clean modeline. However, I can add them back by adding them to the whitelist with ~(add-to-list 'rm-whitelist " REGEX")~. -#+BEGIN_SRC emacs-lisp - (defun rm-whitelist-add (regexp) - "Add a regexp to the whitelist." - (add-to-list 'rm--whitelist-regexps regexp) - (setq rm-whitelist - (mapconcat 'identity rm--whitelist-regexps "\\|"))) +** Recent files - (setq rm--whitelist-regexps '("^$")) +Though I haven't used this feature ... yet, maybe if I use the =C-x +C-r= binding that is suggested (like /everywhere/), it'll be easier +for me to use. - (use-package rich-minority - :custom - (rm-whitelist - (mapconcat 'identity rm--whitelist-regexps "\\|"))) -#+END_SRC -** Fonts -I'm sure there's a better way to do this, but for now, this is the best I've got. I append to the ~face-font-family-alternatives~ because I don't know what kind of weird magic they're doing in there. -#+BEGIN_SRC emacs-lisp - (cuss face-font-family-alternatives - '(("Monospace" "courier" "fixed") - ("Monospace Serif" "Courier 10 Pitch" "Consolas" "Courier Std" "FreeMono" "Nimbus Mono L" "courier" "fixed") - ("courier" "CMU Typewriter Text" "fixed") - ("Sans Serif" "helv" "helvetica" "arial" "fixed") - ("helv" "helvetica" "arial" "fixed") - ;; now mine - ("FixedPitch" "Go Mono" "DejaVu Sans Mono" "Consolas" "fixed") - ("VariablePitch" "Go" "DejaVu Sans" "Georgia" "fixed"))) - - (set-face-attribute 'default nil - :family "FixedPitch" - :height 140) - - (set-face-attribute 'fixed-pitch nil - :family "FixedPitch" - :height 140) - - (set-face-attribute 'variable-pitch nil - :family "VariablePitch" - :height 150) -#+END_SRC -*** Ligatures -These cause big problems with cc-mode (as in, totally freezing everything), so I'm going to comment it out. -#+begin_src emacs-lisp - ;; (use-package ligature - ;; :straight (ligature - ;; :host github - ;; :repo "mickeynp/ligature.el") - ;; :config - ;; (ligature-set-ligatures 'prog-mode - ;; '("++" "--" "/=" "&&" "||" "||=" - ;; "->" "=>" "::" "__" - ;; "==" "===" "!=" "=/=" "!==" - ;; "<=" ">=" "<=>" - ;; "/*" "*/" "//" "///" - ;; "\\n" "\\\\" - ;; "<<" "<<<" "<<=" ">>" ">>>" ">>=" - ;; "|=" "^=" - ;; "**" "--" "---" "----" "-----" - ;; "==" "===" "====" "=====" - ;; "" "-->" "/>" - ;; ":=" "..." ":>" ":<" ">:" "<:" - ;; "::=" ;; add others here - ;; )) - ;; :config - ;; (global-ligature-mode)) -#+end_src -*** [[https://github.com/rolandwalker/unicode-fonts][Unicode fonts]] -#+BEGIN_SRC emacs-lisp - (use-package persistent-soft) +I'm putting =recentf= in a =use-package= declaration, by the way, +because even though it's a part of Emacs, it's conveniently in its own +package. - (use-package unicode-fonts - :after persistent-soft - :config - (unicode-fonts-setup)) - -#+END_SRC -* Editing -** Completion -I was using company, but I think it might've been causing issues with ~awk-mode~, so I'm trying ~hippie-mode~ right now. So far, I'm also enjoying not having a popup all the time. -#+BEGIN_SRC emacs-lisp - (bind-key "M-/" #'hippie-expand) -#+END_SRC -** Ignore case -#+BEGIN_SRC emacs-lisp - (cuss completion-ignore-case t) - (cuss read-buffer-completion-ignore-case t) - (cuss read-file-name-completion-ignore-case t) -#+END_SRC -** Selection & Minibuffer -*** Selectrum & Prescient -#+begin_src emacs-lisp - (use-package selectrum - :config - (selectrum-mode +1)) - - (use-package prescient - :config - (prescient-persist-mode +1)) - - (use-package selectrum-prescient - :after (selectrum prescient) - :config - (selectrum-prescient-mode +1)) -#+end_src -** Search -*** CtrlF for searching -#+BEGIN_SRC emacs-lisp - (use-package ctrlf - :custom - (ctrlf-show-match-count-at-eol nil) - :config - (ctrlf-mode +1) - :bind - ("C-s" . ctrlf-forward-regexp)) -#+END_SRC -*** [[https://github.com/benma/visual-regexp.el][Visual Regexp]] #+begin_src emacs-lisp - (use-package visual-regexp - :bind - ([remap query-replace] . 'vr/query-replace)) -#+end_src -** Undo -#+BEGIN_SRC emacs-lisp - (use-package undo-fu - :bind - ("C-/" . undo-fu-only-undo) - ("C-?" . undo-fu-only-redo)) - - (use-package undo-fu-session - :after no-littering + (use-package recentf + :custom-update + (recentf-exclude + (no-littering-var-directory + no-littering-etc-directory)) :custom - (undo-fu-session-incompatible-files - '("/COMMIT_EDITMSG\\'" - "/git-rebase-todo\\'")) - (undo-fu-session-directory - (no-littering-expand-var-file-name "undos/")) - :config - (global-undo-fu-session-mode +1)) -#+END_SRC -** Visual editing -*** ~zap-to-char~ replacement -#+BEGIN_SRC emacs-lisp - (use-package zop-to-char - :bind - ([remap zap-to-char] . zop-to-char) - ([remap zap-up-to-char] . zop-up-to-char)) -#+END_SRC -*** Operate on a line if there's no current region -#+BEGIN_SRC emacs-lisp - (use-package whole-line-or-region - :config - (whole-line-or-region-global-mode +1)) -#+END_SRC -*** Expand-region -#+BEGIN_SRC emacs-lisp - (use-package expand-region - :bind - ("C-=" . er/expand-region) - ("C-+" . er/contract-region)) -#+END_SRC -*** Volatile highlights -#+BEGIN_SRC emacs-lisp - (use-package volatile-highlights - :config - (volatile-highlights-mode 1)) -#+END_SRC -*** Visual line mode -#+BEGIN_SRC emacs-lisp - (global-visual-line-mode 1) -#+END_SRC -*** A better ~move-beginning-of-line~ -#+BEGIN_SRC emacs-lisp - (defun my/smarter-move-beginning-of-line (arg) - "Move point back to indentation of beginning of line. - - Move point to the first non-whitespace character on this line. - If point is already there, move to the beginning of the line. - Effectively toggle between the first non-whitespace character and - the beginning of the line. - - If ARG is not nil or 1, move forward ARG - 1 lines first. If - point reaches the beginning or end of the buffer, stop there." - (interactive "^p") - (setq arg (or arg 1)) - - ;; Move lines first - (when (/= arg 1) - (let ((line-move-visual nil)) - (forward-line (1- arg)))) - - (let ((orig-point (point))) - (back-to-indentation) - (when (= orig-point (point)) - (move-beginning-of-line 1)))) - - (bind-key "C-a" #'my/smarter-move-beginning-of-line) -#+END_SRC -** Delete the selection when typing -#+BEGIN_SRC emacs-lisp - (delete-selection-mode 1) -#+END_SRC -** Clipboard -#+BEGIN_SRC emacs-lisp - (cuss save-interprogram-paste-before-kill t) -#+END_SRC -** Tabs & Spaces -#+BEGIN_SRC emacs-lisp - (cuss sentence-end-double-space t) - - ;; cf https://dougie.io/emacs/indentation/ - ;; Create a variable for our preferred tab width - (setq custom-tab-width 4) - - ;; Two callable functions for enabling/disabling tabs in Emacs - (defun disable-tabs () (setq indent-tabs-mode nil)) - (defun enable-tabs () - (setq indent-tabs-mode t) - (setq tab-width custom-tab-width)) - - ;; Hooks to Enable Tabs - (add-hook 'prog-mode-hook 'enable-tabs) - ;; Hooks to Disable Tabs - (add-hook 'lisp-mode-hook 'disable-tabs) - (add-hook 'emacs-lisp-mode-hook 'disable-tabs) - - ;; Language-Specific Tweaks - (setq-default python-indent-offset custom-tab-width) ;; Python - (setq-default js-indent-level custom-tab-width) ;; Javascript - - ;; Make the backspace properly erase the tab instead of - ;; removing 1 space at a time. - (setq backward-delete-char-untabify-method 'hungry) - - ;; WARNING: This will change your life - ;; (OPTIONAL) Visualize tabs as a pipe character - "|" - ;; This will also show trailing characters as they are useful to spot. - (setq whitespace-style '(face tabs tab-mark trailing)) - (custom-set-faces - '(whitespace-tab ((t (:foreground "#636363"))))) - (setq whitespace-display-mappings - '((tab-mark 9 [124 9] [92 9]))) ; 124 is the ascii ID for '\|' - (global-whitespace-mode) ; Enable whitespace mode everywhere - - (use-package smart-tabs-mode - :init - (smart-tabs-insinuate 'c 'javascript)) -#+END_SRC -* Programming -** Git -#+BEGIN_SRC emacs-lisp - (use-package magit + (recentf-max-menu-items 100) + (recentf-max-saved-items 100) :bind - ("C-x g" . magit-status) - :config - (add-to-list 'magit-no-confirm 'stage-all-changes)) - - ;; hook into `prescient' - (define-advice magit-list-refs - (:around (orig &optional namespaces format sortby) - prescient-sort) - "Apply prescient sorting when listing refs." - (let ((res (funcall orig namespaces format sortby))) - (if (or sortby - magit-list-refs-sortby - (not selectrum-should-sort-p)) - res - (prescient-sort res)))) - - (when (executable-find "cmake") - (use-package libgit) - (use-package magit-libgit)) - - (use-package forge - :after magit - :custom - (forge-owned-accounts '(("duckwork")))) -#+END_SRC -** Code display -#+BEGIN_SRC emacs-lisp - (add-hook 'prog-mode-hook #'prettify-symbols-mode) -#+END_SRC -*** Parentheses -#+BEGIN_SRC emacs-lisp - (cuss show-paren-style 'mixed) - (show-paren-mode +1) - - (use-package smartparens - :init - (defun acdw/setup-smartparens () - (require 'smartparens-config) - (smartparens-mode +1)) - :hook - (prog-mode . acdw/setup-smartparens)) - - (use-package rainbow-delimiters - :hook - (prog-mode . rainbow-delimiters-mode)) -#+END_SRC -** Line numbers -#+BEGIN_SRC emacs-lisp - (add-hook 'prog-mode-hook - (if (and (fboundp 'display-line-numbers-mode) - (display-graphic-p)) - #'display-line-numbers-mode - #'linum-mode)) -#+END_SRC -** Languages -*** Shell -#+begin_src emacs-lisp - (use-package shfmt - :custom - (shfmt-arguments '("-i" "4" "-ci")) - :hook - (sh-mode . shfmt-on-save-mode)) - - ;; fish - (use-package fish-mode) -#+end_src -*** Lua -#+BEGIN_SRC emacs-lisp - (use-package lua-mode - :mode "\\.lua\\'" - :interpreter "lua") -#+END_SRC -*** Fennel -#+BEGIN_SRC emacs-lisp - (use-package fennel-mode - :mode "\\.fnl\\'") -#+END_SRC -*** Web -#+BEGIN_SRC emacs-lisp - (use-package web-mode - :custom - (web-mode-markup-indent-offset 2) - (web-mode-code-indent-offset 2) - (web-mode-css-indent-offset 2) - :mode (("\\.ts\\'" . web-mode) - ("\\.html?\\'" . web-mode) - ("\\.css?\\'" . web-mode) - ("\\.js\\'" . web-mode))) -#+END_SRC -*** SSH config -#+begin_src emacs-lisp - (use-package ssh-config-mode) -#+end_src -*** Lisp (SLIME) -#+begin_src emacs-lisp - (use-package slime - :when (executable-find "sbcl") - :custom - (inferior-lisp-program "sbcl") - (slime-contribs '(slime-fancy)) - ;;:config - ;;(load (expand-file-name "~/.quicklisp/slime-helper.el")) - ) -#+end_src -* Writing -** Word count -#+begin_src emacs-lisp - (use-package wc-mode - :config - (rm-whitelist-add "WC") - :hook - (text-mode . wc-mode)) -#+end_src -** Visual fill column -#+begin_src emacs-lisp - (use-package visual-fill-column - :custom - (split-window-preferred-function 'visual-fill-column-split-window-sensibly) - (visual-fill-column-center-text t) - (fill-column 80) - :config - (advice-add 'text-scale-adjust - :after #'visual-fill-column-adjust) - :hook - (org-mode . visual-fill-column-mode)) -#+end_src -** Org mode -#+begin_src emacs-lisp - (use-package org - :custom - (org-startup-indented t) - (org-src-tab-acts-natively t) - (org-hide-emphasis-markers t) - (org-fontify-done-headline t) - (org-hide-leading-stars t) - (org-pretty-entities t) - (org-src-window-setup 'current-window) - :hook - (org-mode . variable-pitch-mode)) - - (use-package org-superstar - :hook - (org-mode . org-superstar-mode)) -#+end_src -*** Org export to gemini -#+begin_src emacs-lisp - (use-package ox-gemini - :straight (ox-gemini - :repo "https://git.sr.ht/~abrahms/ox-gemini" - :branch "main")) -#+end_src -* Applications -** Gemini & Gopher -#+BEGIN_SRC emacs-lisp - (use-package elpher - :straight (elpher - :repo "git://thelambdalab.xyz/elpher.git") - :custom - (elpher-certificate-directory - (no-littering-expand-var-file-name "elpher-certificates/")) - (elpher-ipv4-always t) - :config - (defun elpher:eww-browse-url (original url &optional new-window) - "Handle gemini/gopher links with eww." - (cond ((string-match-p "\\`\\(gemini\\|gopher\\)://" url) - (require 'elpher) - (elpher-go url)) - (t (funcall original url new-window)))) - (advice-add 'eww-browse-url :around 'elpher:eww-browse-url) - :bind (:map elpher-mode-map - ("n" . elpher-next-link) - ("p" . elpher-prev-link) - ("o" . elpher-follow-current-link) - ("G" . elpher-go-current)) - :hook - (elpher-mode . visual-fill-column-mode)) - - (use-package gemini-mode - :straight (gemini-mode - :repo "https://git.carcosa.net/jmcbray/gemini.el.git") - :mode "\\.\\(gemini|gmi\\)\\'" - :hook - (gemini-mode . visual-fill-column-mode)) - - (use-package gemini-write - :straight (gemini-write - :repo "https://alexschroeder.ch/cgit/gemini-write")) - - (use-package post-to-gemlog-blue - :straight (post-to-gemlog-blue - :repo "https://git.sr.ht/~acdw/post-to-gemlog-blue.el")) -#+END_SRC -** Pastebin -#+BEGIN_SRC emacs-lisp - (use-package 0x0 - :custom - (0x0-default-service 'ttm)) -#+END_SRC -** Gnus -#+begin_src emacs-lisp - (cuss gnus-select-method - '(nnimap "imap.fastmail.com" - (nnimap-inbox "INBOX") - (nnimap-split-methods default) - (nnimap-expunge t) - (nnimap-stream ssl))) - - (cuss gnus-secondary-select-methods - '((nntp "news.gwene.org"))) -#+end_src -** Nov.el: read Ebooks -#+begin_src emacs-lisp - (use-package nov - :mode ("\\.epub\\'" . nov-mode) - :custom - (nov-text-width t) - :hook - (nov-mode . visual-line-mode) - (nov-mode . visual-fill-column-mode)) -#+end_src -** Circe: IRC -Commented for now while I figure out exactly what I want from IRC, et al. -#+begin_src emacs-lisp - ;; (cuss auth-sources '("~/.authinfo")) - - ;; (defun acdw/fetch-password (&rest params) - ;; (require 'auth-source) - ;; (let ((match (car (apply 'auth-source-search params)))) - ;; (if match - ;; (let ((secret (plist-get match :secret))) - ;; (if (functionp secret) - ;; (funcall secret) - ;; secret)) - ;; (error "Password not found for %S" params)))) - - ;; (defun acdw/nickserv-password (nick server) - ;; (acdw/fetch-password :login nick :machine server)) - - ;; (defun acdw/setup-lui () - ;; (interactive) - ;; (setq right-margin-width 5) - ;; (setq fringes-outside-margins t) - ;; (setq word-wrap t) - ;; (setq wrap-prefix " ") - ;; (setf (cdr (assoc 'continuation fringe-indicator-alist)) nil)) - - ;; (defun acdw/circe-prompt () - ;; (lui-set-prompt - ;; (concat (propertize (concat (buffer-name) ">") - ;; 'face 'circe-prompt-face) - ;; " "))) - - ;; (use-package circe - ;; :init - ;; (defun acdw/setup-circe () - ;; (whitespace-mode -1) - ;; (enable-lui-autopaste)) - ;; :custom - ;; (circe-default-part-message "Peace out, cub scouts") - ;; (circe-default-quit-message "See You Space Cowpokes....") - ;; (circe-default-realname "Case") - ;; (circe-highlight-nick-type 'all) - ;; (circe-reduce-lurker-spam t) - ;; (circe-format-say "{nick:-15s}| {body}") - ;; (circe-format-self-say "{nick:-15s}> {body}") - ;; (circe-format-action " * {nick} {body}") - ;; (circe-format-message " *{nick}* {body}") - ;; (circe-format-message-action " * *{nick}* {body}") - ;; (circe-format-self-action " * {nick} {body}") - ;; (circe-use-cycle-completion t) - ;; (circe-channel-killed-confirmation nil) - ;; (circe-color-nicks-everywhere t) - ;; (circe-default-nick "acdw") - ;; (circe-default-user "acdw") - ;; (circe-server-auto-join-default-type :after-auth) - ;; (lui-time-stamp-position 'right-margin) - ;; (lui-fill-type nil) - ;; (lui-time-stamp-format "%H:%M") - ;; (lui-track-bar-behavior 'before-switch-to-buffer) - ;; (circe-network-options - ;; `(("Freenode" - ;; :tls t - ;; :host "irc.acdw.net" - ;; :port 16789 - ;; :nick "acdw" - ;; :sasl-username "acdw" - ;; :sasl-password "freenode:purple-mountains-majesty" - ;; :channels ("#emacs")) - ;; ("Tilde.chat" - ;; :tls t - ;; :host "irc.acdw.net" - ;; :port 16789 - ;; :nick "acdw" - ;; :sasl-username "acdw" - ;; :sasl-password "tilde.chat:purple-mountains-majesty" - ;; :channels ("#gemini" "#meta" "#team" "#bread")))) - ;; :custom-face - ;; (circe-highlight-nick-face ((t (:inherit bold)))) - ;; (circe-originator-face ((t (:weight bold)))) - ;; (circe-prompt-face ((t (:foreground "blue")))) - ;; (lui-time-stamp-face ((t (:foreground "#808080" :height 0.8)))) - ;; :config - ;; (enable-lui-track-bar) - ;; (enable-circe-color-nicks) - ;; (enable-circe-display-images) - ;; :hook - ;; (circe-channel-mode . acdw/setup-circe) - ;; (circe-chat-mode . acdw/circe-prompt) - ;; (lui-mode . acdw/setup-lui)) -#+end_src -** Elfeed: Feed reader -Elfeed keeps freezing emacs. I'm commenting this for now. -#+begin_src emacs-lisp - ;; (use-package elfeed - ;; :custom - ;; (elfeed-feeds - ;; '(("https://acdw.net/atom.xml" me) - ;; ("https://planet.emacslife.com/atom.xml" emacs programming blog) - ;; ("https://www.xkcd.com/rss.xml" comics) - ;; ("https://portal.mozz.us/gemini/breadpunk.club/~bakersdozen/gemlog/atom.xml" friends) - ;; ("https://kotobank.ch/~vaartis/rss.xml" friends) - ;; ("https://m455.casa/feed.rss" friends) - ;; ("https://eli.li/feed.rss" friends) - ;; ("http://len.falken.ink/" friends) - ;; ("https://cadence.moe/blog/atom.xml?limit=30" friends) - ;; ("https://benjaminwil.info/feed.xml" friends) - ;; ("https://www.5snb.club/rss.xml" friends) - ;; ("https://write.lain.faith/@/haskal/atom.xml" friends) - ;; ("https://p1k3.com/feed" friends) - ;; ))) -#+end_src -* Machine-specific configurations -#+begin_src emacs-lisp - (use-package su - :when *acdw/at-home* + ("C-x C-r" . recentf-open-files) :config - (su-mode 1)) - - (use-package trashed - :when *acdw/at-home* - :custom - (delete-by-moving-to-trash t)) - - (use-package exec-path-from-shell - :when *acdw/at-home* - :demand - :config - (exec-path-from-shell-initialize)) + (recentf-mode 1)) #+end_src -- cgit 1.4.1-21-gabe81