summaryrefslogtreecommitdiff
path: root/.emacs
diff options
context:
space:
mode:
Diffstat (limited to '.emacs')
-rw-r--r--.emacs213
1 files changed, 213 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