-#+title: =aminb='s Literate Emacs Configuration
+#+title: Literate Emacs Configuration of Amin Bandali
#+author: Amin Bandali
#+babel: :cache yes
#+property: header-args :tangle yes
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
#+end_src
Then, decide if you would like to use a byte-compiled init file, and
-set the following variable accordingly:
-
-#+begin_src emacs-lisp
-(defvar a/byte-compiled-init t
- "If non-nil, byte-(re)compile init.el on successful tangles.")
-#+end_src
+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:
** License
#+begin_src emacs-lisp :comments none
-;; Copyright (C) 2018 Amin Bandali <bandali@gnu.org>
+;; Copyright (C) 2018-2019 Amin Bandali <bandali@gnu.org>
;; 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
: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,
#+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
,@args))
#+end_src
+Also, here's a useful function for reloading the init file (useful
+after running =straight-check-all=:
+
+#+begin_src emacs-lisp
+(defun a/reload-init ()
+ "Reload init.el."
+ (interactive)
+ (straight-transaction
+ (straight-mark-transaction-as-init)
+ (load (if a/byte-compiled-init
+ (concat (file-name-sans-extension user-init-file) ".elc")
+ user-init-file))))
+#+end_src
+
*** =use-package=
#+begin_quote
use-package-expand-minimally t))
(setq use-package-always-defer t)
+(require 'bind-key)
#+end_src
-*** Epkg
+*** COMMENT Epkg
#+begin_quote
Browse the Emacsmirror package database
=package.el=-like user interface for browsing the available packages.
#+begin_src emacs-lisp
-(require 'bind-key)
(use-package epkg
:commands (epkg-list-packages epkg-describe-package)
:bind
#+begin_src emacs-lisp
(use-package exec-path-from-shell
- :defer 1
+ :defer 0.4
:init
(setq exec-path-from-shell-arguments nil
exec-path-from-shell-check-startup-files nil)
#+begin_src emacs-lisp
(use-feature server
- :defer 1
+ :defer 0.4
:config (or (server-running-p) (server-mode)))
#+end_src
(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 0.4
+ :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 0.4
+ :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
("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:
("f" . straight-freeze-versions)
("t" . straight-thaw-versions)
("P" . straight-prune-build)
- ("r" . straight-get-recipe)
+ ("g" . straight-get-recipe)
+ ("r" . a/reload-init)
;; M-x ^straight-.*-all$
("a c" . straight-check-all)
("a f" . straight-fetch-all)
In short, my favourite way of life.
-First, we have to resort to a [[https://github.com/raxod502/straight.el#installing-org-with-straightel][hack]] to be able to use the correct
-latest version of Org from upstream.
-
-#+begin_src emacs-lisp
- (use-package git)
-
- (defun org-git-version ()
- "The Git version of org-mode.
- Inserted by installing org-mode or when a release is made."
- (require 'git)
- (let ((git-repo (expand-file-name
- "straight/repos/org/" user-emacs-directory)))
- (string-trim
- (git-run "describe"
- "--match=release\*"
- "--abbrev=6"
- "HEAD"))))
-
- (defun org-release ()
- "The release version of org-mode.
- Inserted by installing org-mode or when a release is made."
- (require 'git)
- (let ((git-repo (expand-file-name
- "straight/repos/org/" user-emacs-directory)))
- (string-trim
- (string-remove-prefix
- "release_"
- (git-run "describe"
- "--match=release\*"
- "--abbrev=0"
- "HEAD")))))
-
-(provide 'org-version)
-#+end_src
-
We will use the =org-plus-contrib= package to get the whole deal:
#+begin_src emacs-lisp
#+begin_src emacs-lisp
(use-feature org
- :defer 2
+ :defer 0.5
:config
(setq org-src-tab-acts-natively t
org-src-preserve-indentation nil
org-edit-src-content-indentation 0
- org-email-link-description-format "Email %c: %s" ; %.30s
+ org-link-email-description-format "Email %c: %s" ; %.30s
org-highlight-latex-and-related '(entities)
org-use-speed-commands t
org-startup-folded 'content
org-catch-invisible-edits 'show-and-error
org-log-done 'time)
(add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp") t)
- :bind (:map org-mode-map ("M-L" . org-insert-last-stored-link))
+ :bind
+ (("C-c a o a" . org-agenda)
+ :map org-mode-map
+ ("M-L" . org-insert-last-stored-link))
:hook ((org-mode . org-indent-mode)
(org-mode . auto-fill-mode)
(org-mode . flyspell-mode))
:custom
+ (org-agenda-files '("~/usr/org/todos/personal.org"
+ "~/usr/org/todos/masters.org"))
+ (org-agenda-start-on-weekday 0)
(org-latex-packages-alist '(("" "listings") ("" "color")))
:custom-face
'(org-block-begin-line ((t (:foreground "#5a5b5a" :background "#1d1f21"))))
#+begin_src emacs-lisp
(use-package magit
- :defer 2
+ :defer 0.5
:bind (("C-x g" . magit-status)
("s-g s" . magit-status)
("s-g l" . magit-log-buffer-file))
#+begin_src emacs-lisp
(use-feature recentf
- :defer 0.5
+ :defer 0.2
:config
(add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?:")
(setq recentf-max-saved-items 40))
#+begin_src emacs-lisp
(use-package ivy
- :defer 0.6
+ :defer 0.3
:bind
(:map ivy-minibuffer-map
([escape] . keyboard-escape-quit)
#+begin_src emacs-lisp
(use-feature eshell
- :defer 2
+ :defer 0.5
:commands eshell
:bind ("C-c a s e" . eshell)
:config
(mode . python-mode)
(mode . c-mode)
(mode . c++-mode)
+ (mode . java-mode)
(mode . emacs-lisp-mode)
(mode . scheme-mode)
(mode . haskell-mode)
("emacs"
(or
(name . "^\\*scratch\\*$")
- (name . "^\\*Messages\\*$"))))))
+ (name . "^\\*Messages\\*$")))
+ ("erc" (mode . erc-mode)))))
(ibuffer-formats
'((mark modified read-only locked " "
(name 18 18 :left :elide)
#+begin_src emacs-lisp
(use-package company
- :defer 3
+ :defer 0.6
:bind
(:map company-active-map
([tab] . company-complete-common-or-cycle)
#+begin_src emacs-lisp
(use-package flycheck
- :defer 3
+ :defer 0.6
:hook (prog-mode . flycheck-mode)
:bind
(:map flycheck-mode-map
;; http://endlessparentheses.com/ispell-and-apostrophes.html
(use-package ispell
- :defer 3
+ :defer 0.6
:config
;; ’ can be part of a word
(setq ispell-local-dictionary-alist
#+begin_src emacs-lisp
(eval-when-compile (defvar lean-mode-map))
(use-package lean-mode
- :defer 1
+ :defer 0.4
:bind (:map lean-mode-map
("S-SPC" . company-complete))
:config
:hook (web-mode css-mode html-mode sgml-mode))
#+end_src
-** COMMENT Java
+** Java
-*** meghanada
+*** COMMENT meghanada
#+begin_src emacs-lisp
(use-package meghanada
:hook (java-mode . meghanada-mode))
#+end_src
-*** lsp-java
+*** COMMENT lsp-java
#+begin_comment
dependencies:
:after (treemacs))
#+end_src
+*** COMMENT 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
#+begin_src emacs-lisp
(use-package which-key
- :defer 1
+ :defer 0.4
:config
(which-key-add-key-based-replacements
;; prefixes for global prefixes and minor modes
"C-x v" "version control"
;; prefixes for my personal bindings
"C-c a" "applications"
+ "C-c a e" "erc"
+ "C-c a o" "org"
"C-c a s" "shells"
"C-c p" "package-management"
- "C-c p e" "package-management/epkg"
+ ;; "C-c p e" "package-management/epkg"
"C-c p s" "straight.el"
"C-c psa" "all"
"C-c psp" "package"
#+begin_src emacs-lisp
(use-package crux ; results in Waiting for git... [2 times]
- :defer 1
+ :defer 0.4
:bind (("C-c b k" . crux-kill-other-buffers)
("C-c d" . crux-duplicate-current-line-or-region)
("C-c D" . crux-duplicate-and-comment-current-line-or-region)
#+begin_src emacs-lisp
(use-package helpful
- :defer 3
+ :defer 0.6
:bind
(("C-S-h c" . helpful-command)
("C-S-h f" . helpful-callable) ; helpful-function
#+begin_src emacs-lisp
(use-package unkillable-scratch
- :defer 3
+ :defer 0.6
:config
(unkillable-scratch 1)
:custom
#+begin_src emacs-lisp
(use-package boxquote
- :defer 3
+ :defer 0.6
:bind
(:prefix-map a/boxquote-prefix-map
:prefix "C-c q"
#+begin_src emacs-lisp
(use-package typo
- :defer 2
+ :defer 0.5
:config
(typo-global-mode 1)
:hook (text-mode . typo-mode))
#+begin_src emacs-lisp
(use-package hl-todo
- :defer 4
+ :defer 0.5
:config
(global-hl-todo-mode))
#+end_src
#+begin_src emacs-lisp
(use-package shrink-path
- :defer 2
+ :defer 0.5
:after eshell
:config
(defun +eshell/prompt ()
#+begin_src emacs-lisp
(use-package multi-term
- :defer 3
+ :defer 0.6
:bind (("C-c a s m" . multi-term-dedicated-toggle)
:map term-mode-map
("C-c C-j" . term-char-mode)
("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 0.6
+ :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
(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.*"
- (gcc-self . t)))
+ '(("gnu\\.deepspec"
+ (to-address . "deepspec@lists.cs.princeton.edu")
+ (to-list . "deepspec@lists.cs.princeton.edu"))
+ ("gnu\\.emacs-devel"
+ (to-address . "emacs-devel@gnu.org")
+ (to-list . "emacs-devel@gnu.org"))
+ ("gnu\\.emacs-orgmode"
+ (to-address . "emacs-orgmode@gnu.org")
+ (to-list . "emacs-orgmode@gnu.org"))
+ ("gnu\\.emacsconf-discuss"
+ (to-address . "emacsconf-discuss@gnu.org")
+ (to-list . "emacsconf-discuss@gnu.org"))
+ ("gnu\\.fencepost-users"
+ (to-address . "fencepost-users@gnu.org")
+ (to-list . "fencepost-users@gnu.org"))
+ ("gnu\\.gnunet-developers"
+ (to-address . "gnunet-developers@gnu.org")
+ (to-list . "gnunet-developers@gnu.org"))
+ ("gnu\\.guile-devel"
+ (to-address . "guile-devel@gnu.org")
+ (to-list . "guile-devel@gnu.org"))
+ ("gnu\\.guix-devel"
+ (to-address . "guix-devel@gnu.org")
+ (to-list . "guix-devel@gnu.org"))
+ ("gnu\\.haskell-art"
+ (to-address . "haskell-art@we.lurk.org")
+ (to-list . "haskell-art@we.lurk.org"))
+ ("gnu\\.haskell-cafe"
+ (to-address . "haskell-cafe@haskell.org")
+ (to-list . "haskell-cafe@haskell.org"))
+ ("gnu\\.help-gnu-emacs"
+ (to-address . "help-gnu-emacs@gnu.org")
+ (to-list . "help-gnu-emacs@gnu.org"))
+ ("gnu\\.info-gnu-emacs"
+ (to-address . "info-gnu-emacs@gnu.org")
+ (to-list . "info-gnu-emacs@gnu.org"))
+ ("gnu\\.info-guix"
+ (to-address . "info-guix@gnu.org")
+ (to-list . "info-guix@gnu.org"))
+ ("gnu\\.notmuch"
+ (to-address . "notmuch@notmuchmail.org")
+ (to-list . "notmuch@notmuchmail.org"))
+ ("gnu\\.parabola-dev"
+ (to-address . "dev@lists.parabola.nu")
+ (to-list . "dev@lists.parabola.nu"))
+ ("gnu\\.webmasters"
+ (to-address . "webmasters@gnu.org")
+ (to-list . "webmasters@gnu.org"))
+ ("gnu\\.www-commits"
+ (to-address . "www-commits@gnu.org")
+ (to-list . "www-commits@gnu.org"))
+ ("gnu\\.www-discuss"
+ (to-address . "www-discuss@gnu.org")
+ (to-list . "www-discuss@gnu.org"))
+ ("gnu\\.~bandali\\.public-inbox"
+ (to-address . "~bandali/public-inbox@lists.sr.ht")
+ (to-list . "~bandali/public-inbox@lists.sr.ht"))
+ ("gnu\\.~sircmpwn\\.srht-admins"
+ (to-address . "~sircmpwn/sr.ht-admins@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-admins@lists.sr.ht"))
+ ("gnu\\.~sircmpwn\\.srht-announce"
+ (to-address . "~sircmpwn/sr.ht-announce@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-announce@lists.sr.ht"))
+ ("gnu\\.~sircmpwn\\.srht-dev"
+ (to-address . "~sircmpwn/sr.ht-dev@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-dev@lists.sr.ht"))
+ ("gnu\\.~sircmpwn\\.srht-discuss"
+ (to-address . "~sircmpwn/sr.ht-discuss@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-discuss@lists.sr.ht"))
+ ("gnu.*"
+ (gcc-self . t))
+ ("gnu\\."
+ (subscribed . t)))
gnus-large-newsgroup 50
gnus-home-directory (no-littering-expand-var-file-name "gnus/")
gnus-directory (concat gnus-home-directory "news/")
(concat local lapsed))))
(bind-keys
:map gnus-article-mode-map
- ("r" . gnus-article-reply-with-original)
- ("R" . gnus-article-wide-reply-with-original)
("M-L" . org-store-link)))
(use-feature gnus-sum
:config
(bind-keys
:map gnus-summary-mode-map
- ("r" . gnus-summary-reply-with-original)
- ("R" . gnus-summary-wide-reply-with-original)
("M-L" . org-store-link))
:hook (gnus-summary-mode . a/no-mouse-autoselect-window))
:config
(setq gnus-posting-styles
'((".*"
- (address "amin@aminb.org")
- (body "\nBest,\namin\n")
+ (address "amin@bndl.org")
+ (body "\nBest,\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 "Added 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
(use-feature gnus-group
:config
- (setq gnus-permanently-visible-groups "\\((INBOX\\|gnu$\\)"))
+ (setq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)"))
(use-feature mm-decode
:config
#+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)
message-kill-buffer-on-exit t
message-send-mail-function 'message-send-mail-with-sendmail
message-sendmail-envelope-from 'header
+ message-subscribed-address-functions
+ '(gnus-find-subscribed-addresses)
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)
#+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
("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
#+begin_src emacs-lisp
-;; https://github.com/girzel/ebdb/issues/72
-(use-package csv-mode)
-
(use-package ebdb
:straight (:host github :repo "girzel/ebdb")
:after gnus
(gnus-harvest-install)))
#+end_src
-* Blogging
+* IRC
:PROPERTIES:
-:CUSTOM_ID: blogging
+:CUSTOM_ID: irc
:END:
-** [[https://ox-hugo.scripter.co][ox-hugo]]
+Now with ERC!
#+begin_src emacs-lisp
-(use-package ox-hugo
- :after ox
- :demand)
-
-(use-feature ox-hugo-auto-export
- :demand)
+(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
* Post initialization