;;; init.el --- Tom-Emacs Interface -*- lexical-binding: t; -*- ;; Copyright (C) 2018 Tom Willemse ;; Author: Tom Willemse ;; Keywords: local ;; 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 ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; This is my Emacs configuration. It has gone through many iterations ;; before and may yet go through many more iterations. ;;; Code: (eval-and-compile (add-to-list 'load-path (format "%sinit/" default-directory)) (mapc (lambda (d) (add-to-list 'load-path d)) (directory-files (format "%svendor-lisp/" default-directory) t "^[^.]")) (add-to-list 'load-path (format "%ssite-lisp/" default-directory)) (let ((loaddefs (format "%ssite-lisp/site-autoloads.el" default-directory))) (when (file-exists-p loaddefs) (load loaddefs)))) (require 'oni-helpers) (require 'package) (eval-and-compile (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))) (eval-and-compile (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))) (eval-and-compile (package-initialize)) (eval-when-compile (let* ((not-installed (seq-remove 'package-installed-p package-selected-packages)) (available (seq-filter (lambda (p) (assq p package-archive-contents)) not-installed)) (difference (- (length not-installed) (length available)))) (when (> difference 0) (silently "Refresh packages" (package-refresh-contents))) (when available (mapc (lambda (p) (package-install p t)) available)))) (setq backup-directory-alist `((".*" . ,(oni:data-location "backup-files/")))) (add-to-list 'auto-save-file-name-transforms `(".*" ,(oni:data-location "auto-save-files/") t) :append) (setq auto-save-list-file-prefix (oni:data-location "auto-save-list/.saves-")) (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode)) (global-set-key (kbd "C-M-SPC") 'er/expand-region) (global-set-key (kbd "M-+") 'mc/mark-next-like-this) (global-set-key (kbd "C-c (") 'embrace-commander) (global-set-key (kbd "C-c o") 'oni-hydra-org/body) (global-set-key (kbd "C-c m") 'oni-hydra-magit/body) (require 'destroy-trailing-whitespace) (global-destroy-trailing-whitespace-mode) (setq require-final-newline t) (setq-default indent-tabs-mode nil) (setq-default tab-width 4) (setq sentence-end-double-space nil) (setq inhibit-startup-screen t) (add-to-list 'default-frame-alist '(font . "Fantasque Sans Mono-15")) (add-to-list 'default-frame-alist '(internal-border-width . 15)) (menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1) (setq-default cursor-type '(bar . 2)) (setq-default truncate-lines t) (global-unset-key (kbd "C-z")) (defalias 'yes-or-no-p 'y-or-n-p) (show-paren-mode) (add-to-list 'custom-theme-load-path (concat user-emacs-directory "vendor-lisp/yoshi-theme")) (load-theme 'yoshi :no-confirm) (require 'diminish) (require 'ivy) (diminish 'ivy-mode) (ivy-mode) (require 'counsel) (setq counsel-find-file-ignore-regexp (rx (or (and bos ".") (and ".zwc" eos)))) (counsel-mode) (diminish 'counsel-mode) (eval-when-compile (require 'bookmark)) (setq bookmark-default-file (oni:data-location "bookmarks")) (setq user-full-name "Tom Willemse" user-mail-address "tom@ryuslash.org") (eval-when-compile (require 'align)) (with-eval-after-load 'align ;; Keep these in order. They are each added to the _front_ of the ;; list and are applied in order. Changing their order will change ;; the results. (add-to-list 'align-rules-list `(css-closing-brace (regexp . ,(rx (group (0+ whitespace)) "}" eol)) (group . (1)) (modes . '(scss-mode css-mode)))) (add-to-list 'align-rules-list `(css-colons (regexp . ,(rx bol (0+ whitespace) (1+ (any (?a . ?z) ?- ?$)) ":" (group (0+ whitespace)) (0+ nonl) ";" eol)) (group . (1)) (modes . '(scss-mode css-mode)) (repeat . t))) (add-to-list 'align-rules-list `(css-opening-brace (regexp . ,(rx bol (0+ whitespace) (0+ (any ?# ?. ?, ?\s ?& ?: ?- (?a . ?z) (?A . ?Z) (?0 . ?9))) (any (?a . ?z) (?A . ?Z) (?0 . ?9)) (group (0+ whitespace)) "{" (0+ nonl))) (group . (1)) (modes . '(scss-mode css-mode))))) (with-eval-after-load 'align (add-to-list 'align-rules-list `(php-array-arrow (regexp . ,(rx any (group whitespace) "=>" any)) (group . (1)) (modes . '(php-mode web-mode)) (repeat . t)))) (eval-when-compile (require 'browse-url)) (with-eval-after-load 'browse-url (setq browse-url-browser-function 'browse-url-firefox)) (add-hook 'minibuffer-setup-hook 'electric-pair-local-mode) (require 'shackle) (shackle-mode) (with-eval-after-load 'shr (load "oni-shr-init")) (with-eval-after-load 'company (load "oni-company-init")) (with-eval-after-load 'paredit (diminish 'paredit-mode)) (electric-indent-mode -1) (defun oni:switch-newline-keys () "Switch the C-j and RET keys in the local buffer." (if electric-indent-mode (progn (local-set-key (kbd "C-j") 'newline) (local-set-key (kbd "RET") 'electric-newline-and-maybe-indent)) (local-unset-key (kbd "C-j")) (local-unset-key (kbd "RET")))) (add-hook 'electric-indent-local-mode-hook #'oni:switch-newline-keys) (add-hook 'flycheck-mode-hook 'flycheck-cask-setup) (with-eval-after-load 'flycheck (mapc (lambda (c) (delq c flycheck-checkers)) '(python-pylint python-pyflakes))) (with-eval-after-load 'flycheck (setq flycheck-highlighting-mode 'columns)) (with-eval-after-load 'flycheck (require 'flycheck-pos-tip) (flycheck-pos-tip-mode)) (with-eval-after-load 'flycheck (setq flycheck-mode-line-prefix "✓")) (with-eval-after-load 'autorevert (diminish 'auto-revert-mode (propertize (concat " " (char-to-string #xf021)) 'face '(:family "Font Awesome" :height 0.75)))) (diminish 'auto-fill-function (propertize (concat " " (char-to-string #xf149)) 'face '(:family "Font Awesome" :height 0.75))) (require 'diff-hl) (global-diff-hl-mode) (defun oni:with-diff-hl-p4-args (orig-fun &rest args) (let ((p4-lowlevel-diff-switches '("-du0"))) (apply orig-fun args))) (with-eval-after-load 'vc-p4 (add-function :around (symbol-function 'diff-hl-changes-buffer) #'oni:with-diff-hl-p4-args)) (diminish 'isearch-mode (propertize (concat " " (char-to-string #xf002)) 'face '(:family "Font Awesome" :height 0.75))) (setq projectile-known-projects-file (oni:data-location "projectile-bookmarks.eld")) (require 'projectile) (with-eval-after-load 'projectile (setq projectile-mode-line '(:eval (if (file-remote-p default-directory) " P" (let ((name (projectile-project-name))) (if (string= "-" name) "" (format " P[%s]" name))))))) (setq projectile-cache-file (oni:data-location "projectile.cache")) (projectile-mode) (setq projectile-completion-system 'ivy) (add-to-list 'projectile-project-root-files "yarn.lock") (with-eval-after-load 'server (diminish 'server-buffer-clients (propertize (concat " " (char-to-string #xf233)) 'face '(:family "Font Awesome" :height 0.75)))) (with-eval-after-load 'slime (setq slime-lisp-implementations '((sbcl ("sbcl" "--noinform") :coding-system utf-8-unix) (clisp ("clisp") :coding-system utf-8-unix))) (setq slime-default-lisp 'sbcl) (slime-setup '(slime-fancy slime-company))) (with-eval-after-load 'js (load "oni-js-mode-init")) (with-eval-after-load 'php-mode (load "oni-php-mode-init")) (with-eval-after-load 'sh-mode (load "oni-sh-mode-init")) (with-eval-after-load 'css-mode (load "oni-css-mode-init")) (with-eval-after-load 'elisp-mode (load "oni-emacs-lisp-mode-init")) (with-eval-after-load 'scheme (load "oni-scheme-init")) (with-eval-after-load 'compile (load "oni-compilation-init")) (with-eval-after-load 'cc-mode (load "oni-java-init")) (add-hook 'ielm-mode-hook 'paredit-mode) (autoload 'mbsync-conf-mode "mbsync-conf-mode" "Major mode for editing mbsync configuration files." :interactive) (add-to-list 'auto-mode-alist '("\\.mbsyncrc\\'" . mbsync-conf-mode)) (autoload 'msmtprc-mode "msmtprc-mode" "Major mode for editing msmtp configuration files." :interactive) (add-to-list 'auto-mode-alist '("\\.msmtprc\\'" . msmtprc-mode)) (add-hook 'git-commit-mode-hook 'electric-quote-local-mode) (add-hook 'python-mode-hook 'electric-pair-local-mode) (add-hook 'python-mode-hook 'flycheck-mode) (add-hook 'web-mode-hook 'oni-whitespace-only-tabs-mode) (add-hook 'makefile-mode-hook 'oni-whitespace-only-tabs-mode) (add-hook 'makefile-mode-hook 'electric-pair-local-mode) (with-eval-after-load 'clojure-mode (require 'clojure-mode-extra-font-locking)) (add-hook 'clojure-mode-hook 'paredit-mode) (add-hook 'clojure-mode-hook 'rainbow-delimiters-mode) (eval-when-compile (require 'inf-lisp)) (defun oni:clojure-set-inferior-lisp () (setq inferior-lisp-program "lein repl")) (add-hook 'clojure-mode-hook 'oni-clojure-add-font-lock) (add-hook 'clojure-mode-hook 'oni-clojure-add-indent) (with-eval-after-load 'cider (setq cider-repl-pop-to-buffer-on-connect t)) (setq cider-show-error-buffer t cider-auto-select-error-buffer t) (setq cider-repl-history-file (oni:data-location "cider-history")) (setq cider-repl-wrap-history t) (add-hook 'cider-repl-mode-hook 'paredit-mode) (add-hook 'c-mode-hook 'electric-pair-local-mode) (add-hook 'c-mode-hook 'electric-indent-local-mode) (add-hook 'lisp-mode-hook 'paredit-mode) (add-hook 'lisp-mode-hook 'rainbow-delimiters-mode) (add-hook 'lisp-mode-hook 'company-mode) (with-eval-after-load 'js2-mode (load "oni-js2-init")) (add-hook 'html-mode-hook 'electric-pair-local-mode) (with-eval-after-load 'cmake-mode (load "oni-cmake-init")) (with-eval-after-load 'cc-mode (load "oni-cpp-init")) (with-eval-after-load 'dired (load "oni-dired-init")) (with-eval-after-load 'magit (load "oni-magit-init")) (with-eval-after-load 'ediff (load "oni-ediff-init")) (with-eval-after-load 'eshell (load "oni-eshell-init")) (with-eval-after-load 'slack (load "oni-slack-init")) (with-eval-after-load 'circe (load "oni-circe-init")) (eval-when-compile (require 'lui)) (with-eval-after-load 'lui (setq lui-time-stamp-position 'right-margin)) (with-eval-after-load 'lui (setq lui-time-stamp-format "%H:%M")) (defun oni:set-circe-margin-width () (setq right-margin-width 5)) (add-hook 'lui-mode-hook #'oni:set-circe-margin-width) (defun oni:set-lui-prompt-wrap-prefix () (setq wrap-prefix " ")) (add-hook 'lui-mode-hook #'oni:set-lui-prompt-wrap-prefix) (add-hook 'lui-mode-hook 'visual-line-mode) (setq lui-fill-type nil) (eval-when-compile (require 'jabber)) (setq jabber-account-list `((,(concat "ryuslash@dukgo.com/" (system-name)) (:connection-type . starttls)))) (setq jabber-avatar-cache-directory (oni:data-location "jabber/avatars/") jabber-history-dir (oni:data-location "jabber/hist/")) (setq jabber-chat-buffer-format "+%n" jabber-chat-foreign-prompt-format "%t %n " jabber-chat-local-prompt-format "%t %n " jabber-chat-delayed-time-format "%H:%M" jabber-groupchat-buffer-format "++%n" jabber-groupchat-prompt-format "%t %n ") (setq jabber-chat-buffer-show-avatar nil jabber-vcard-avatars-publish nil jabber-vcard-avatars-retrieve nil) (setq jabber-chat-fill-long-lines nil) (add-hook 'jabber-chat-mode-hook 'visual-line-mode) (setq jabber-chatstates-confirm nil) (setq jabber-muc-colorize-local t jabber-muc-colorize-foreign t) (setq jabber-history-enabled t jabber-use-global-history nil) (setq jabber-roster-show-bindings nil jabber-show-offline-contacts nil) (add-hook 'jabber-roster-mode-hook 'oni-jabber-set-roster-mode-line) (add-hook 'jabber-alert-message-hooks 'jabber-message-libnotify) (add-hook 'jabber-alert-muc-hooks 'jabber-muc-libnotify) (with-eval-after-load 'jabber-alert (remove-hook 'jabber-alert-presence-hooks 'jabber-presence-echo)) (add-hook 'jabber-alert-presence-hooks 'oni-jabber-show-status-in-buffer) (defun oni:set-default-directory () (setq default-directory "~/")) (add-hook 'jabber-chat-mode-hook 'oni:set-default-directory) (with-eval-after-load 'gnus (load "oni-gnus-init")) (with-eval-after-load 'org (load "oni-org-init")) (add-to-list 'grep-files-aliases '("js" . "*.js *.jsx *.json")) (add-to-list 'grep-files-aliases '("css" . "*.css *.less *.sass *.scss")) (setq custom-file (concat user-emacs-directory "custom.el")) (load custom-file) (provide 'init) ;;; init.el ends here