summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKΓ©vin Le Gouguec <kevin.legouguec@gmail.com>2018-01-31 20:55:42 +0100
committerKΓ©vin Le Gouguec <kevin.legouguec@gmail.com>2018-01-31 20:58:42 +0100
commitc6320f872750910fcd636bf0de362e6935ff7ac9 (patch)
treef5aae9b186d8ecd3866c02fa856e3f812073e50e
parent803454514104e6f3c5b1186a883b2babd1f37bb7 (diff)
downloaddotfiles-c6320f872750910fcd636bf0de362e6935ff7ac9.tar.xz
Add Emacs dotfiles
-rw-r--r--.emacs213
-rw-r--r--.emacs-custom.el68
-rw-r--r--.gnus106
3 files changed, 387 insertions, 0 deletions
diff --git a/.emacs b/.emacs
new file mode 100644
index 0000000..6a68b2a
--- /dev/null
+++ b/.emacs
@@ -0,0 +1,213 @@
+;; -*- lexical-binding: t -*-
+
+;; Packages and Custom initialization
+
+;; Letting Custom run *before* initializing packages seems to result
+;; in packages resetting some of their variables, eg page-break-lines
+;; resets global-page-break-lines-mode to nil. Cue Custom shrugging,
+;; "changed outside Customize".
+
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
+(package-initialize)
+
+(setq custom-file "~/.emacs-custom.el")
+(load custom-file)
+
+
+;; Key bindings
+
+(define-key input-decode-map (kbd "C-h") (kbd "DEL"))
+
+(global-set-key (kbd "C-x C-b") 'ibuffer)
+
+;; C-c [:alpha:] is reserved for users - let's make good use of it
+
+(global-set-key (kbd "C-c c") 'compile)
+(global-set-key (kbd "C-c f") 'auto-fill-mode)
+(global-set-key (kbd "C-c m") 'man)
+(global-set-key (kbd "C-c p") 'electric-pair-mode)
+(global-set-key (kbd "C-c t") 'toggle-truncate-lines)
+(global-set-key (kbd "C-c v") 'visual-line-mode)
+(global-set-key (kbd "C-c w c") 'whitespace-cleanup)
+(global-set-key (kbd "C-c w f") 'page-break-lines-mode)
+(global-set-key (kbd "C-c w m") 'whitespace-mode)
+(global-set-key (kbd "C-c w t") 'set-tab-width)
+
+(rg-enable-default-bindings)
+
+;; TODO: define my own input method, instead of overloading TeX
+;; https://www.emacswiki.org/emacs/TeXInputMethod explains why the
+;; with-temp-buffer shenanigans are necessary.
+;; Quoth (elisp)Input Methods:
+;; > How to define input methods is not yet documented in this manual,
+;; > but here we describe how to use them.
+;; Regardless, `register-input-method', `quail-define-rules' may help
+;; achieving that.
+(with-temp-buffer
+ (activate-input-method "TeX")
+ (let ((quail-current-package (assoc "TeX" quail-package-alist)))
+ (quail-define-rules ((append . t))
+ ("~~" ?β‰ˆ) ("~=" ?β‰Š)
+ ;; would like to add ("^=" ?≙), but "^=" already exists
+ ("..." ?…)
+ ("-->" ?β†’) ("-/>" ?↛) ("==>" ?β‡’) ("=/>" ?⇏)
+ ("<--" ?←) ("</-" ?β†š) ("<==" ?⇐) ("</=" ?⇍)
+ ("<->" ?↔) ("<=>" ?⇔))))
+
+
+;; Window management
+
+(when window-system
+ (load-theme 'eighters t)
+ ;; Bindings ala Terminator
+ (global-set-key [C-tab] 'other-window)
+ (global-set-key (kbd "C-S-o") 'split-window-below)
+ (global-set-key (kbd "C-S-e") 'split-window-right)
+ (global-set-key (kbd "C-+") 'text-scale-adjust)
+ (global-set-key (kbd "C--") 'text-scale-adjust)
+ (global-set-key (kbd "C-0") 'text-scale-adjust)
+ (global-set-key (kbd "C-S-<up>") 'enlarge-window)
+ (global-set-key (kbd "C-S-<down>") 'shrink-window)
+ (global-set-key (kbd "C-S-<right>") 'enlarge-window-horizontally)
+ (global-set-key (kbd "C-S-<left>") 'shrink-window-horizontally))
+
+
+;; Online packages configuration
+
+;; So long, Will Mengarini.
+(delight 'abbrev-mode nil "abbrev")
+(delight 'auto-fill-function "⏎" t)
+(delight 'auto-revert-mode "⟳" "autorevert")
+(delight 'auto-revert-tail-mode "–" "autorevert")
+(delight 'hs-minor-mode "…" "hideshow")
+(delight 'page-break-lines-mode nil "page-break-lines")
+(delight 'visual-line-mode "β€Έ" t)
+;; TODO: eldoc-mode, isearch-mode, narrowing, scroll-lock-mode
+
+(defun my/magit-mode-hook ()
+ (when window-system
+ (local-set-key [C-tab] 'other-window)
+ (local-set-key (kbd "C-i") 'magit-section-cycle)
+ (local-set-key (kbd "<tab>") 'magit-section-toggle)))
+
+(add-hook 'magit-mode-hook 'my/magit-mode-hook)
+
+
+;; Major modes configuration
+
+(defun my/c-modes-hook ()
+ (c-set-style "bsd")
+ (c-set-offset 'arglist-close 0))
+
+(add-hook 'c-mode-common-hook 'my/c-modes-hook)
+
+(defun my/python-hook ()
+ (setq-local forward-sexp-function nil))
+
+(add-hook 'python-mode-hook 'my/python-hook)
+
+(defun my/compilation-notify (buffer results)
+ (let* ((title (buffer-name buffer))
+ (status (if (string-equal results "finished\n") "success" "failure"))
+ (icon (format "~/Pictures/icons/compilation-%s.png" status)))
+ (require 'notifications)
+ (notifications-notify :title title :body results :app-icon icon
+ :timeout 3000)))
+
+(add-to-list 'compilation-finish-functions 'my/compilation-notify)
+
+(defun my/makefile-hook ()
+ ;; I would rather align backslashes with spaces rather than tabs;
+ ;; however, I would also like indent-tabs-mode to remain non-nil.
+ (local-set-key (kbd "C-c C-\\") (make-tabless 'makefile-backslash-region))
+ (local-set-key (kbd "M-q") (make-tabless 'fill-paragraph)))
+
+(add-hook 'makefile-mode-hook 'my/makefile-hook)
+
+(defun my/shell-hook ()
+ (setq truncate-lines nil)
+ (setq-local font-lock-comment-face 'default)
+ (setq-local font-lock-string-face 'default)
+ (setq-local recenter-positions '(top middle bottom)))
+
+(add-hook 'shell-mode-hook 'my/shell-hook)
+
+;; What I mean:
+;; (defun my/erc-hook ()
+;; (add-to-list 'erc-modules 'log)
+;; (delq 'fill erc-modules)
+;; (erc-update-modules))
+;;
+;; That cannot work because erc-update-modules only iterates over
+;; erc-modules, so it will not act on the `fill' module.
+;;
+;; I do *not* want to maintain an exhaustive and manually curated list
+;; of ERC modules; I just want to add/remove a few ones. Customizing
+;; erc-{log,fill}-mode does not work: the contents of erc-modules
+;; take precedence.
+;;
+;; My best attempt at solving this is thus abusing erc-modules's
+;; setter function, which will iterate over items in the old value,
+;; and disable those that are absent from the new one.
+(defun my/erc-hook ()
+ (let ((new-modules
+ (delete-dups (remq 'fill (cons 'log erc-modules)))))
+ (customize-set-variable 'erc-modules new-modules)))
+
+(add-hook 'erc-mode-hook 'my/erc-hook)
+
+
+;; Helper functions and miscellaneous settings.
+
+;; TODO: copy documentation from F.
+(defun make-tabless (f)
+ "Make a function which will disable tabs while running F."
+ (lambda () (interactive)
+ (let ((indent-tabs-mode nil))
+ (call-interactively f))))
+
+(defun set-tab-width (&optional arg)
+ (interactive "P")
+ (let ((new-width (cond (arg (prefix-numeric-value arg))
+ ((= tab-width 4) 8)
+ (4)))
+ (old-width tab-width))
+ ;; TODO: for some reason, set-variable takes effect immediately,
+ ;; but setq(-local)? do not: I need to move the cursor before tabs
+ ;; are re-drawn.
+ (set-variable 'tab-width new-width)
+ (message "changed from %s to %s" old-width new-width)))
+
+(defun my/froggify ()
+ (ispell-change-dictionary "fr")
+ (setq-local colon-double-space nil)
+ (setq-local sentence-end-double-space nil)
+ (setq-local fill-nobreak-predicate
+ (cons 'fill-french-nobreak-p fill-nobreak-predicate))
+ (setq-local my/froggified t))
+
+(defun my/unfroggify ()
+ (ispell-change-dictionary "default")
+ (setq-local colon-double-space t)
+ (setq-local sentence-end-double-space t)
+ (setq-local fill-nobreak-predicate
+ (remq 'fill-french-nobreak-p fill-nobreak-predicate))
+ (setq-local my/froggified nil))
+
+(defun my/croak ()
+ (interactive)
+ (if (and (boundp 'my/froggified) my/froggified)
+ (my/unfroggify)
+ (my/froggify)))
+
+(defun buffer-justify-full ()
+ (setq default-justification 'full))
+
+;; Font stuff (🀷 🀦)
+(set-fontset-font "fontset-default" nil (font-spec :name "Symbola") nil 'append)
+
+;; TODO: fringe fun: hideshowvis, git gutter…
+;; TODO: decruftify mode-line
+;; TODO: visual-line vs word-wrap
+;; TODO: check for an idiomatic way to append thru dir-locals
diff --git a/.emacs-custom.el b/.emacs-custom.el
new file mode 100644
index 0000000..60b6095
--- /dev/null
+++ b/.emacs-custom.el
@@ -0,0 +1,68 @@
+(put 'dired-find-alternate-file 'disabled nil)
+(put 'downcase-region 'disabled nil)
+(put 'upcase-region 'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(after-save-hook
+ (quote
+ (executable-make-buffer-file-executable-if-script-p)))
+ '(async-shell-command-buffer (quote new-buffer))
+ '(backup-directory-alist (quote (("" . "~/.emacs.backup"))))
+ '(column-number-mode t)
+ '(comint-scroll-show-maximum-output nil)
+ '(delete-selection-mode t)
+ '(dired-listing-switches "-al -Fhv --group-directories-first")
+ '(ediff-merge-split-window-function (quote split-window-vertically))
+ '(ediff-split-window-function (quote split-window-horizontally))
+ '(electric-pair-mode t)
+ '(erc-log-channels-directory "~/.irc-logs")
+ '(erc-log-write-after-insert t)
+ '(erc-log-write-after-send t)
+ '(erc-nick "peniblec")
+ '(erc-prompt-for-password nil)
+ '(eshell-scroll-show-maximum-output nil)
+ '(gdb-many-windows t)
+ '(git-commit-setup-hook
+ (quote
+ (git-commit-save-message git-commit-setup-changelog-support git-commit-turn-on-auto-fill git-commit-turn-on-flyspell git-commit-propertize-diff with-editor-usage-message buffer-justify-full)))
+ '(global-page-break-lines-mode t nil (page-break-lines))
+ '(icomplete-mode t)
+ '(indent-tabs-mode nil)
+ '(inhibit-startup-screen t)
+ '(isearch-allow-scroll t)
+ '(magit-log-arguments (quote ("--graph" "--color" "--decorate" "-n256")))
+ '(magit-log-section-arguments (quote ("--graph" "--color" "--decorate" "-n256")))
+ '(markdown-asymmetric-header t)
+ '(markdown-command "pandoc -s")
+ '(markdown-enable-math t)
+ '(markdown-header-scaling t)
+ '(menu-bar-mode nil)
+ '(package-selected-packages
+ (quote
+ (rg delight paradox flycheck magit markdown-mode page-break-lines rust-mode wgrep)))
+ '(page-break-lines-modes (quote (fundamental-mode text-mode prog-mode special-mode)))
+ '(paradox-execute-asynchronously t)
+ '(paradox-github-token t)
+ '(paradox-spinner-type (quote random))
+ '(python-fill-docstring-style (quote pep-257-nn))
+ '(python-shell-interpreter "python3")
+ '(scroll-bar-mode nil)
+ '(scroll-conservatively 101)
+ '(scroll-preserve-screen-position t)
+ '(send-mail-function (quote smtpmail-send-it))
+ '(show-paren-mode t)
+ '(split-width-threshold 120)
+ '(tool-bar-mode nil)
+ '(truncate-lines t)
+ '(visual-line-fringe-indicators (quote (left-curly-arrow right-curly-arrow))))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ )
diff --git a/.gnus b/.gnus
new file mode 100644
index 0000000..1b06407
--- /dev/null
+++ b/.gnus
@@ -0,0 +1,106 @@
+;; user-full-name: from /etc/passwd, set with chfn.
+;; user-mail-address: from EMAIL environment variable in ~/.profile.
+
+;; In ~/.authinfo.gpg:
+;; machine imap.gmail.com login LOGIN password PASSWORD port 993
+;; machine smtp.gmail.com login LOGIN password PASSWORD port 587
+
+(setq gnus-select-method
+ '(nnimap "gmail"
+ (nnimap-address "imap.gmail.com")
+ (nnimap-server-port 993)
+ (nniamp-stream ssl)
+ (nnmail-expiry-target "nnimap+gmail:[Gmail]/Trash")
+ (nnmail-expiry-wait immediate))
+ gnus-thread-sort-functions
+ '(gnus-thread-sort-by-number
+ gnus-thread-sort-by-most-recent-date)
+ gnus-treat-display-smileys nil)
+
+(setq smtpmail-smtp-server "smtp.gmail.com"
+ smtpmail-smtp-service 587)
+
+;; Key bindings:
+;;
+;; When browsing group buffer:
+;;
+;; L list all groups
+;; RET view unread mail in group
+;; C-u RET view all mail in group
+;; g refresh
+;;
+;; When browsing summary buffer:
+;;
+;; B m move message to group
+;; / N fetch new
+;; M-g refresh (expire, move, fetch new, show unread)
+;; C-u M-g refresh (expire, move, fetch new, show all)
+;; r reply
+;; R reply (quoting)
+;; S w reply-all
+;; S W reply-all (quoting)
+;; C-c C-f forward
+;; d mark read
+;; M-u clear marks (≑ mark unread)
+;; E expire
+;; # mark for next action
+;; M-#, M P u unmark for next action
+;;
+;; Both:
+;;
+;; m compose
+;;
+;; When reading article:
+;;
+;; o save attachment at point
+;;
+;; When composing:
+;; C-c C-c send
+;; C-c C-a attach
+;;
+;; FAQ:
+;;
+;; - how to see *all mails*, not just unread?
+;; - C-u RET
+;;
+;; - how to delete mail?
+;; - E to mark as expired
+;; - C-u M-g to refresh
+;;
+;; - how to list most-recent mails on top?
+;; - cf. gnus-thread-sort-functions
+;;
+;; - how to close a mail without going back to the group list?
+;; - = to make summary full-screen
+;;
+;; - how to get contact completion?
+;; - by installing a MELPA plugin (bbdb); bleh
+;; - something something ecomplete?
+;;
+;; - how to refresh?
+;; - summary buffer:
+;; - / N (fetch new)
+;; - M-g (expire, move, fetch & redisplay)
+;; - group buffer: g
+;;
+;; - what do all those letters mean?
+;; (info gnus Marking Articles)
+;; - O old ≑ read during previous session
+;; - R just read
+;; - r manually marked as read
+;; - A answered
+;; - E expirable
+;; - G cancelled (e.g. moved somewhere else)
+;; - . unseen
+;;
+;; TODOs:
+;;
+;;- gnus-summary-line-format (πŸ“Ž for attachments)
+;;
+;; - browse mailing list
+;; https://emacs.stackexchange.com/questions/5298/reading-mailing-list-archives-in-emacs
+;;
+;;- describe-key is mostly useless in article mode:
+;; > X runs the command gnus-article-read-summary-keys
+;;
+;;- detect possibly missing attachments from keywords