X-Git-Url: https://git.shemshak.org/~bandali/configs/blobdiff_plain/0c6e40cb03d8071b50c5906a6ae0a9d4cafed822..2a292da98e0fa7fe82324b5c4d999b4fb18e8527:/init.org?ds=sidebyside diff --git a/init.org b/init.org index 684bbf1..fd734b1 100644 --- a/init.org +++ b/init.org @@ -1,4 +1,4 @@ -#+title: =aminb='s Literate Emacs Configuration +#+title: Literate Emacs Configuration of Amin Bandali #+author: Amin Bandali #+babel: :cache yes #+property: header-args :tangle yes @@ -32,6 +32,44 @@ anyway. So, I've opted to use =straight.el=. I also used Borg for a few months, but decided to try =straight.el= which allows direct use of the various package archives. +** Installation +:PROPERTIES: +:CUSTOM_ID: installation +:END: + +To use this config for your Emacs, first you need to clone this repo, +then tangle =init.org= into =init.el=, and optionally byte-compile +=init.el=. + +First, clone the repository and =cd= into it: + +#+begin_src sh :tangle no +git clone https://git.sr.ht/~bandali/dotfiles ~/.emacs.d +cd ~/.emacs.d +#+end_src + +Then, decide if you would like to use a byte-compiled init file, and +set the [[#byte-compiled-init][a/byte-compiled-init]] variable accordingly. + +Now, first tangle =init.org=, and only if you chose to have a +byte-compiled init, build init as well: + +#+begin_src sh :tangle no +make tangle-init +make build-init +#+end_src + +If you'd like to use a byte-compiled init, it's important that it be +recompiled whenever =init.el= is generated from an updated =init.org=. +Not only does my setup automatically and asynchronously tangle +=init.org= to =init.el= every time you edit and save =init.org= in GNU +Emacs, it will also invoke =make build-init= if you set +=a/byte-compiled-init= to =t= above, so you wouldn't have to worry +about manually tangling and compiling your init file whenever you +change it. The output of the last byte-compilation in the current +session is kept in a =*compilation*= buffer, which will automatically +be displayed if compilation fails. + * Contents :toc_1:noexport: - [[#about][About]] @@ -67,7 +105,7 @@ file. ** License #+begin_src emacs-lisp :comments none -;; Copyright (C) 2018 Amin Bandali +;; Copyright (C) 2018-2019 Amin Bandali ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -99,6 +137,21 @@ file. :CUSTOM_ID: initial-setup :END: +** Byte-compiled init preference +:PROPERTIES: +:CUSTOM_ID: byte-compiled-init +:END: + +If you would like a byte-compiled init file, set the following +variable to ~t~, otherwise set it to ~nil~. + +#+begin_src emacs-lisp +(defvar a/byte-compiled-init t + "If non-nil, byte-(re)compile init.el on successful tangles.") +#+end_src + +You can click on [[#installation][Installation]] to jump back up there if you like :) + ** Emacs initialization I'd like to do a couple of measurements of Emacs' startup time. First, @@ -161,7 +214,7 @@ but for now I've decided to keep them enabled. See documentation for #+begin_src emacs-lisp (setq user-full-name "Amin Bandali" - user-mail-address "amin@aminb.org") + user-mail-address "amin@bndl.org") #+end_src ** Package management @@ -256,11 +309,13 @@ and without compromising on performance. #+begin_src emacs-lisp (straight-use-package 'use-package) -(if nil ; set to t when need to debug init - (setq use-package-verbose t - use-package-expand-minimally nil - use-package-compute-statistics t - debug-on-error t) +(if nil ; set to t when need to debug init + (progn + (setq use-package-verbose t + use-package-expand-minimally nil + use-package-compute-statistics t + debug-on-error t) + (require 'use-package)) (setq use-package-verbose nil use-package-expand-minimally t)) @@ -282,8 +337,8 @@ database, low-level functions for querying the database, and a (use-package epkg :commands (epkg-list-packages epkg-describe-package) :bind - (("C-c P e d" . epkg-describe-package) - ("C-c P e p" . epkg-list-packages)) + (("C-c p e d" . epkg-describe-package) + ("C-c p e p" . epkg-list-packages)) :config (setq epkg-repository "~/.emacs.d/straight/repos/epkgs/") (eval-when-compile (defvar ivy-initial-inputs-alist)) @@ -347,7 +402,8 @@ in my shell. (use-package exec-path-from-shell :defer 1 :init - (setq exec-path-from-shell-check-startup-files nil) + (setq exec-path-from-shell-arguments nil + exec-path-from-shell-check-startup-files nil) :config (exec-path-from-shell-initialize) ;; while we're at it, let's fix access to our running ssh-agent @@ -441,6 +497,33 @@ buffers and/or modes. (setq mouse-autoselect-window nil)) #+end_src +** Better scrolling (arguably) + +#+begin_src emacs-lisp +(setq ;; scroll-margin 1 + ;; scroll-conservatively 10000 + scroll-step 1 + scroll-conservatively 10 + scroll-preserve-screen-position 1) + +(use-feature mwheel + :defer 1 + :config + (setq mouse-wheel-scroll-amount '(1 ((shift) . 1)) ; one line at a time + mouse-wheel-progressive-speed nil ; don't accelerate scrolling + mouse-wheel-follow-mouse t)) ; scroll window under mouse + +(use-feature pixel-scroll + :defer 1 + :config (pixel-scroll-mode 1)) +#+end_src + +** Ask for GPG passphrase in minibuffer + +#+begin_src emacs-lisp +(setq epg-pinentry-mode 'loopback) +#+end_src + ** Libraries #+begin_src emacs-lisp @@ -696,6 +779,8 @@ for this. ** Bindings +Some bindings for functions from built-in GNU Emacs packages: + #+begin_src emacs-lisp (bind-keys ("C-c a i" . ielm) @@ -703,21 +788,55 @@ for this. ("C-c e b" . eval-buffer) ("C-c e r" . eval-region) + ("C-c e i" . emacs-init-time) + ("C-c e u" . emacs-uptime) + ("C-c F m" . make-frame-command) ("C-c F d" . delete-frame) ("C-c F D" . delete-other-frames) ("C-c o" . other-window) - ("C-c Q" . save-buffers-kill-terminal) - ("C-S-h C" . describe-char) ("C-S-h F" . describe-face) - ("C-x K" . kill-this-buffer) + ("C-x k" . kill-this-buffer) + ("C-x K" . kill-buffer) ("s-p" . beginning-of-buffer) ("s-n" . end-of-buffer)) + +(when (display-graphic-p) + (unbind-key "C-z" global-map)) +#+end_src + +While at it, let's bind a few for some =straight-*= functions too: + +#+begin_src emacs-lisp +(bind-keys + :prefix-map a/straight-prefix-map + :prefix "C-c p s" + ("u" . straight-use-package) + ("f" . straight-freeze-versions) + ("t" . straight-thaw-versions) + ("P" . straight-prune-build) + ("r" . straight-get-recipe) + ;; M-x ^straight-.*-all$ + ("a c" . straight-check-all) + ("a f" . straight-fetch-all) + ("a m" . straight-merge-all) + ("a n" . straight-normalize-all) + ("a F" . straight-pull-all) + ("a P" . straight-push-all) + ("a r" . straight-rebuild-all) + ;; M-x ^straight-.*-package$ + ("p c" . straight-check-package) + ("p f" . straight-fetch-package) + ("p m" . straight-merge-package) + ("p n" . straight-normalize-package) + ("p F" . straight-pull-package) + ("p P" . straight-push-package) + ("p r" . straight-rebuild-package)) #+end_src ** Packages @@ -853,9 +972,13 @@ file. (defvar a/show-async-tangle-time nil "Show the time spent tangling the file.") - (defvar a/async-tangle-post-compile "make bi" + (defvar a/async-tangle-post-compile + (when a/byte-compiled-init "make build-init") "If non-nil, pass to `compile' after successful tangle.") + ;; TODO: look into why directly byte-compiling init.el causes a + ;; number of problems, including magit-status not loading (busy + ;; waiting). (defvar a/async-tangle-byte-recompile nil "If non-nil, byte-recompile the file on successful tangle.") @@ -990,7 +1113,6 @@ There's no way I could top that, so I won't attempt to. #+begin_src emacs-lisp (use-package counsel - :defer 0.6 :after ivy :bind (([remap execute-extended-command] . counsel-M-x) ([remap find-file] . counsel-find-file) @@ -1089,6 +1211,7 @@ There's no way I could top that, so I won't attempt to. (mode . python-mode) (mode . c-mode) (mode . c++-mode) + (mode . java-mode) (mode . emacs-lisp-mode) (mode . scheme-mode) (mode . haskell-mode) @@ -1096,7 +1219,8 @@ There's no way I could top that, so I won't attempt to. ("emacs" (or (name . "^\\*scratch\\*$") - (name . "^\\*Messages\\*$")))))) + (name . "^\\*Messages\\*$"))) + ("erc" (mode . erc-mode))))) (ibuffer-formats '((mark modified read-only locked " " (name 18 18 :left :elide) @@ -1237,6 +1361,7 @@ Highlight matching parens. #+begin_src emacs-lisp (use-feature paren + :demand :config (show-paren-mode)) #+end_src @@ -1628,9 +1753,9 @@ instead. :hook (web-mode css-mode html-mode sgml-mode)) #+end_src -** COMMENT Java +** Java -*** meghanada +*** COMMENT meghanada #+begin_src emacs-lisp (use-package meghanada @@ -1641,7 +1766,7 @@ instead. :hook (java-mode . meghanada-mode)) #+end_src -*** lsp-java +*** COMMENT lsp-java #+begin_comment dependencies: @@ -1709,6 +1834,24 @@ treemacs :after (treemacs)) #+end_src +*** eclim + +#+begin_src emacs-lisp +(use-package eclim + :bind (:map eclim-mode-map ("S-SPC" . company-complete)) + :hook ((java-mode . eclim-mode) + (eclim-mode . (lambda () + (make-local-variable 'company-idle-delay) + (defvar company-idle-delay) + ;; (setq company-idle-delay 0.7) + (setq company-idle-delay nil)))) + :custom + (eclim-auto-save nil) + ;; (eclimd-default-workspace "~/src/eclipse-workspace-exp") + (eclim-executable "~/.p2/pool/plugins/org.eclim_2.8.0/bin/eclim") + (eclim-eclipse-dirs '("~/usr/eclipse/dsl-2018-09/eclipse"))) +#+end_src + ** geiser #+begin_src emacs-lisp @@ -1761,20 +1904,23 @@ Emacs package that displays available keybindings in popup "C-x v" "version control" ;; prefixes for my personal bindings "C-c a" "applications" + "C-c a e" "erc" "C-c a s" "shells" - "C-c P" "package-management" - "C-c P e" "package-management/epkg" - "C-c P s" "package-management/straight.el" + "C-c p" "package-management" + "C-c p e" "package-management/epkg" + "C-c p s" "straight.el" + "C-c psa" "all" + "C-c psp" "package" "C-c c" "compile-and-comments" "C-c e" "eval" "C-c f" "files" "C-c F" "frames" "C-S-h" "help(ful)" "C-c m" "multiple-cursors" - "C-c p" "projectile" - "C-c p s" "projectile/search" - "C-c p x" "projectile/execute" - "C-c p 4" "projectile/other-window" + "C-c P" "projectile" + "C-c P s" "projectile/search" + "C-c P x" "projectile/execute" + "C-c P 4" "projectile/other-window" "C-c q" "boxquote" "s-g" "magit" "s-o" "outline" @@ -1792,7 +1938,10 @@ Emacs package that displays available keybindings in popup "C-c C-e" "web/element" "C-c C-t" "web/tags") - (which-key-mode)) + (which-key-mode) + :custom + (which-key-add-column-padding 5) + (which-key-max-description-length 32)) #+end_src ** theme @@ -1879,7 +2028,7 @@ Emacs package that displays available keybindings in popup #+begin_src emacs-lisp (use-package projectile - :bind-keymap ("C-c p" . projectile-command-map) + :bind-keymap ("C-c P" . projectile-command-map) :config (projectile-mode) @@ -2003,9 +2152,10 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. (propertize (+eshell--current-git-branch) 'face 'font-lock-function-name-face) "\n" - (propertize "λ" 'face 'eshell-prompt-face) + ;; "λ" + ;; (propertize "λ" 'face 'eshell-prompt) ;; needed for the input text to not have prompt face - (propertize " " 'face 'default)))) + (propertize "λ " 'face 'default)))) (defun +eshell--current-git-branch () (let ((branch (car (loop for match in (split-string (shell-command-to-string "git branch") "\n") @@ -2090,6 +2240,29 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. ("a" . mc/mark-all-like-this)))) #+end_src +** forge + +#+begin_src emacs-lisp +(use-package forge + :after magit + :demand) +#+end_src + +** yasnippet + +#+begin_src emacs-lisp +(use-package yasnippet + :defer 3 + :config + (defconst yas-verbosity-cur yas-verbosity) + (setq yas-verbosity 2) + (add-to-list 'yas-snippet-dirs "~/src/git/guix/etc/snippets") + (yas-reload-all) + (setq yas-verbosity yas-verbosity-cur) + :hook + (text-mode . yas-minor-mode)) +#+end_src + * Email :PROPERTIES: :CUSTOM_ID: email @@ -2121,13 +2294,19 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. (nnimap-address "127.0.0.1") (nnimap-server-port 143) (nnimap-authenticator plain) - (nnimap-user "amin@aminb.org")) + (nnimap-user "amin@bndl.org")) (nnimap "uwaterloo" (nnimap-stream plain) (nnimap-address "127.0.0.1") (nnimap-server-port 143) (nnimap-authenticator plain) - (nnimap-user "abandali@uwaterloo.ca"))) + (nnimap-user "abandali@uwaterloo.ca")) + (nnimap "csclub" + (nnimap-stream plain) + (nnimap-address "127.0.0.1") + (nnimap-server-port 143) + (nnimap-authenticator plain) + (nnimap-user "abandali@csclub.uw"))) gnus-message-archive-group "nnimap+amin:Sent" gnus-parameters '(("gnu.*" @@ -2140,7 +2319,11 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. gnus-save-newsrc-file nil gnus-read-newsrc-file nil gnus-interactive-exit nil - gnus-gcc-mark-as-read t)) + gnus-gcc-mark-as-read t) + :config + (require 'ebdb) + (require 'ebdb-mua) + (require 'ebdb-gnus)) (use-feature gnus-art :config @@ -2190,21 +2373,26 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. :config (setq gnus-posting-styles '((".*" - (address "amin@aminb.org") + (address "amin@bndl.org") (body "\nBest,\namin\n") (eval (setq a/message-cite-say-hi t))) ("gnu.*" - (address "bandali@gnu.org")) + (address "bandali@gnu.org") + (eval (set (make-local-variable 'message-user-fqdn) "fencepost.gnu.org"))) ((header "subject" "ThankCRM") (to "webmasters-comment@gnu.org") - (body "\nAdded to 2018supporters.html.\n\nMoving to campaigns.\n\n-amin\n") + (body "\nAdded to 2019supporters.html.\n\nMoving to campaigns.\n\n-amin\n") (eval (setq a/message-cite-say-hi nil))) ("nnimap\\+uwaterloo:.*" (address "abandali@uwaterloo.ca") - (gcc "\"nnimap+uwaterloo:Sent Items\""))))) + (gcc "\"nnimap+uwaterloo:Sent Items\"")) + ("nnimap\\+csclub:.*" + (address "abandali@csclub.uwaterloo.ca") + (gcc "nnimap+csclub:Sent"))))) (use-feature gnus-topic - :hook (gnus-group-mode . gnus-topic-mode)) + :hook (gnus-group-mode . gnus-topic-mode) + :config (setq gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n")) (use-feature gnus-agent :config @@ -2213,7 +2401,7 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. (use-feature gnus-group :config - (setq gnus-permanently-visible-groups "\\((INBOX\\|gnu$\\)")) + (setq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)")) (use-feature mm-decode :config @@ -2236,6 +2424,16 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. #+begin_src emacs-lisp (use-feature message :config + ;; redefine for a simplified In-Reply-To header + ;; (see https://todo.sr.ht/~sircmpwn/lists.sr.ht/67) + (defun message-make-in-reply-to () + "Return the In-Reply-To header for this message." + (when message-reply-headers + (let ((from (mail-header-from message-reply-headers)) + (msg-id (mail-header-id message-reply-headers))) + (when from + msg-id)))) + (defconst a/message-cite-style-format "On %Y-%m-%d %l:%M %p, %N wrote:") (defconst message-cite-style-bandali '((message-cite-function 'message-cite-original) @@ -2254,8 +2452,8 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]]. message-send-mail-function 'message-send-mail-with-sendmail message-sendmail-envelope-from 'header message-dont-reply-to-names - "\\(\\(.*@aminb\\.org\\)\\|\\(amin@bandali\\.me\\)\\|\\(\\(aminb?\\|mab\\|bandali\\)@gnu\\.org\\)\\|\\(\\(m\\|a\\(min\\.\\)?\\)bandali@uwaterloo\\.ca\\)\\)" - message-user-fqdn "aminb.org") + "\\(\\(amin@bndl\\.org\\)\\|\\(.*@\\(aminb\\|amin\\.bndl\\)\\.org\\)\\|\\(\\(bandali\\|aminb?\\|mab\\)@gnu\\.org\\)\\|\\(a\\(min\\.\\)?bandali@uwaterloo\\.ca\\)\\|\\(abandali@csclub\\.uwaterloo\\.ca\\)\\)") + (require 'company-ebdb) :hook (;; (message-setup . mml-secure-message-sign-pgpmime) (message-mode . flyspell-mode) (message-mode . (lambda () @@ -2281,6 +2479,10 @@ Convenient footnotes in =message-mode=. #+begin_src emacs-lisp (use-feature footnote :after message + ;; :config + ;; (setq footnote-start-tag "" + ;; footnote-end-tag "" + ;; footnote-style 'unicode) :bind (:map message-mode-map :prefix-map a/footnote-prefix-map @@ -2291,11 +2493,7 @@ Convenient footnotes in =message-mode=. ("d" . footnote-delete-footnote) ("g" . footnote-goto-footnote) ("r" . footnote-renumber-footnotes) - ("s" . footnote-set-style)) - :config - (setq footnote-start-tag "" - footnote-end-tag "" - footnote-style 'unicode)) + ("s" . footnote-set-style))) #+end_src ** ebdb @@ -2303,7 +2501,6 @@ Convenient footnotes in =message-mode=. #+begin_src emacs-lisp (use-package ebdb :straight (:host github :repo "girzel/ebdb") - :defer 2 :after gnus :bind (:map gnus-group-mode-map ("e" . ebdb)) :config @@ -2320,14 +2517,11 @@ Convenient footnotes in =message-mode=. ;; (ebdb-complete-enable)) (use-package company-ebdb - :defer 2 :config (defun company-ebdb--post-complete (_) nil)) (use-feature ebdb-gnus - :defer 3 :after ebdb - :demand :custom (ebdb-gnus-window-configuration '(article @@ -2338,9 +2532,7 @@ Convenient footnotes in =message-mode=. (ebdb-gnus 0.3)))))) (use-feature ebdb-mua - :defer 3 :after ebdb - :demand ;; :custom (ebdb-mua-pop-up nil) ) @@ -2352,9 +2544,13 @@ Convenient footnotes in =message-mode=. ;; :after ebdb) #+end_src -** COMMENT message-x +** message-x #+begin_src emacs-lisp +(use-package message-x) +#+end_src + +#+begin_src emacs-lisp :tangle no (use-package message-x :custom (message-x-completion-alist @@ -2379,6 +2575,30 @@ Convenient footnotes in =message-mode=. (gnus-harvest-install))) #+end_src +* IRC +:PROPERTIES: +:CUSTOM_ID: irc +:END: + +Now with ERC! + +#+begin_src emacs-lisp +(use-package znc + :straight (:host nil :repo "https://git.bndl.org/amin/znc.el") + :bind (("C-c a e e" . znc-erc) + ("C-c a e a" . znc-all)) + :config + (let ((pwd (let ((auth (auth-source-search :host "znca"))) + (cond + ((null auth) (error "Couldn't find znca's authinfo")) + (t (funcall (plist-get (car auth) :secret))))))) + (setq znc-servers + `(("znc.bndl.org" 1337 t + ((freenode "amin/freenode" ,pwd))) + ("znc.bndl.org" 1337 t + ((moznet "amin/moznet" ,pwd))))))) +#+end_src + * Blogging :PROPERTIES: :CUSTOM_ID: blogging @@ -2388,10 +2608,8 @@ Convenient footnotes in =message-mode=. #+begin_src emacs-lisp (use-package ox-hugo - :after ox) - -(use-feature ox-hugo-auto-export - :after ox-hugo) + :after ox + :demand) #+end_src * Post initialization