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]]
** 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
;; Main engine start...
-(setq straight-repository-branch "develop")
+(setq straight-repository-branch "develop"
+ straight-check-for-modifications '(check-on-save find-when-checking))
(defun a/bootstrap-straight ()
(defvar bootstrap-version)
#+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))
(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))
(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
(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
** Bindings
+Some bindings for functions from built-in GNU Emacs packages:
+
#+begin_src emacs-lisp
(bind-keys
("C-c a i" . ielm)
("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))
#+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
The packages in this section are absolutely essential to my everyday
#+begin_src emacs-lisp
(use-feature org
- :defer 0.5
+ :defer 2
:config
(setq org-src-tab-acts-natively t
org-src-preserve-indentation nil
org-catch-invisible-edits 'show-and-error
org-log-done 'time)
(add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp") t)
- (font-lock-add-keywords
- 'org-mode
- '(("[ \t]*\\(#\\+\\(BEGIN\\|END\\|begin\\|end\\)_\\(\\S-+\\)\\)[ \t]*\\([^\n:]*\\)"
- (1 '(:foreground "#5a5b5a" :background "#292b2b") t) ; directive
- (3 '(:foreground "#81a2be" :background "#292b2b") t) ; kind
- (4 '(:foreground "#c5c8c6") t))) ; title
- t)
:bind (:map org-mode-map ("M-L" . org-insert-last-stored-link))
:hook ((org-mode . org-indent-mode)
(org-mode . auto-fill-mode)
(setq org-latex-listings 'listings
;; org-latex-prefer-user-labels t
)
- (add-to-list 'org-latex-packages-alist '("" "listings"))
- (add-to-list 'org-latex-packages-alist '("" "color"))
(add-to-list 'org-latex-classes
'("IEEEtran" "\\documentclass[11pt]{IEEEtran}"
- ("\\section{%s}" . "\\section*{%s}")
- ("\\subsection{%s}" . "\\subsection*{%s}")
+ ("\\section{%s}" . "\\section*{%s}")
+ ("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
- ("\\paragraph{%s}" . "\\paragraph*{%s}")
- ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
- t))
-
-(use-feature ox-beamer
- :demand
- :after ox)
+ ("\\paragraph{%s}" . "\\paragraph*{%s}")
+ ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
+ t)
+ (require 'ox-beamer))
#+end_src
**** asynchronous tangle
(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.")
`(lambda (result)
(if result
(progn
- (setq byte-compile-warnings '(not noruntime unresolved))
+ ;; (setq byte-compile-warnings '(not noruntime unresolved))
(message "Tangled %s%s"
,file-nodir
(if a/show-async-tangle-time
#+begin_src emacs-lisp
(use-package magit
- :defer 1
+ :defer 2
:bind (("C-x g" . magit-status)
("s-g s" . magit-status)
("s-g l" . magit-log-buffer-file))
#+begin_src emacs-lisp
(use-feature eshell
- :defer 1
+ :defer 2
: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)
#+begin_src emacs-lisp
(use-feature paren
+ :demand
:config (show-paren-mode))
#+end_src
+** simple (for column numbers)
+
+#+begin_src emacs-lisp
+(use-feature simple
+ :config (column-number-mode))
+#+end_src
+
** =savehist=
Save minibuffer history.
#+begin_src emacs-lisp
(use-package company
- :defer 1
+ :defer 3
:bind
(:map company-active-map
([tab] . company-complete-common-or-cycle)
** [[https://coq.inria.fr][Coq]] (with [[https://github.com/ProofGeneral/PG][Proof General]])
#+begin_src emacs-lisp
-(use-package proof-site
+(use-package proof-site ; Proof General
:straight proof-general)
#+end_src
: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 geiser
+*** 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
(use-package geiser)
(setq geiser-guile-load-path "~/src/git/guix"))
#+end_src
-** COMMENT guix
+** guix
#+begin_src emacs-lisp
(use-package guix)
;; prefixes for my personal bindings
"C-c a" "applications"
"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"
"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
#+begin_src emacs-lisp
(use-package smart-mode-line
:commands (sml/apply-theme)
+ :demand
:config
(sml/setup))
#+end_src
** theme helper functions
#+begin_src emacs-lisp
+(defvar a/org-mode-font-lock-keywords
+ '(("[ \t]*\\(#\\+\\(BEGIN\\|END\\|begin\\|end\\)_\\(\\S-+\\)\\)[ \t]*\\([^\n:]*\\)"
+ (1 '(:foreground "#5a5b5a" :background "#292b2b") t) ; directive
+ (3 '(:foreground "#81a2be" :background "#292b2b") t) ; kind
+ (4 '(:foreground "#c5c8c6") t)))) ; title
+
(defun a/lights-on ()
"Enable my favourite light theme."
(interactive)
(mapc #'disable-theme custom-enabled-themes)
(load-theme 'tangomod t)
- (sml/apply-theme 'automatic))
+ (sml/apply-theme 'automatic)
+ (font-lock-remove-keywords
+ 'org-mode a/org-mode-font-lock-keywords))
(defun a/lights-off ()
"Go dark."
(interactive)
(mapc #'disable-theme custom-enabled-themes)
(load-theme 'doom-tomorrow-night t)
- (sml/apply-theme 'automatic))
+ (sml/apply-theme 'automatic)
+ (font-lock-add-keywords
+ 'org-mode a/org-mode-font-lock-keywords t))
(bind-keys
("s-t d" . a/lights-off)
#+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)
#+begin_src emacs-lisp
(use-package helpful
- :defer 1
+ :defer 3
:bind
(("C-S-h c" . helpful-command)
("C-S-h f" . helpful-callable) ; helpful-function
:config
(unkillable-scratch 1)
:custom
- (unkillable-scratch-behavior 'do-nothing)
(unkillable-buffers '("^\\*scratch\\*$" "^\\*Messages\\*$")))
#+end_src
#+begin_src emacs-lisp
(use-package shrink-path
:defer 2
+ :after eshell
:config
- (setq eshell-prompt-regexp "\\(.*\n\\)*λ "
- eshell-prompt-function #'+eshell/prompt)
-
(defun +eshell/prompt ()
(let ((base/dir (shrink-path-prompt default-directory)))
(concat (propertize (car base/dir)
(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")
collect match))))
(if (not (eq branch nil))
(concat " " (substring branch 2))
- ""))))
+ "")))
+ (setq eshell-prompt-regexp "\\(.*\n\\)*λ "
+ eshell-prompt-function #'+eshell/prompt))
#+end_src
** [[https://github.com/peterwvj/eshell-up][eshell-up]]
#+begin_src emacs-lisp
(use-package eshell-up
- :commands eshell-up
- :after eshell)
+ :after eshell
+ :commands eshell-up)
#+end_src
** multi-term
#+begin_src emacs-lisp
(use-package multi-term
- :defer 1
+ :defer 3
: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 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
(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.*"
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
(address "bandali@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))
(use-feature gnus-group
:config
- (setq gnus-permanently-visible-groups "\\((INBOX\\|gnu$\\)"))
+ (setq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)"))
(use-feature mm-decode
:config
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\\)\\)"
+ "\\(\\(.*@aminb\\.org\\)\\|\\(amin@bandali\\.me\\)\\|\\(\\(aminb?\\|mab\\|bandali\\)@gnu\\.org\\)\\|\\(\\(m\\|a\\(min\\.\\)?\\)bandali@uwaterloo\\.ca\\)\\|\\(abandali@csclub\\.uwaterloo\\.ca\\)\\)"
message-user-fqdn "aminb.org")
+ (require 'company-ebdb)
:hook (;; (message-setup . mml-secure-message-sign-pgpmime)
(message-mode . flyspell-mode)
(message-mode . (lambda ()
#+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
;; (ebdb-complete-enable))
(use-package company-ebdb
- :after (:all company message)
:config
- (defun company-ebdb--post-complete (_) nil)
- :hook
- (message-mode . (lambda ()
- (add-to-list (make-local-variable 'company-backends)
- 'company-ebdb))))
+ (defun company-ebdb--post-complete (_) nil))
(use-feature ebdb-gnus
:after ebdb
- :demand
:custom
(ebdb-gnus-window-configuration
'(article
(use-feature ebdb-mua
:after ebdb
- :demand
;; :custom (ebdb-mua-pop-up nil)
)
;; :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
#+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
* COMMENT Local Variables :ARCHIVE:
# Local Variables:
# eval: (add-hook 'after-save-hook #'a/async-babel-tangle 'append 'local)
-# eval: (typo-mode -1)
+# eval: (when (featurep 'typo (typo-mode -1)))
# End: