;;; Package (require 'package) ;; Prevent loading packages twice (setq package-enable-at-startup nil) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize) (defalias '/refresh 'package-refresh-contents) (defalias '/install 'package-install) ;;; Use-Package (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) (require 'use-package) ;;; No-Littering (use-package no-littering :ensure t :init (setq no-littering-etc-directory (expand-file-name "auto-package-configuration/" user-emacs-directory)) (setq no-littering-var-directory (expand-file-name "auto-package-data/" user-emacs-directory)) (setq auto-save-file-name-transforms `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))) (setq custom-file (no-littering-expand-etc-file-name "custom.el")) ;; Create `custom-file' if it doesn't exist (or (file-exists-p custom-file) (make-empty-file custom-file))) ;;; Configuration Directory Structure (defconst user-system-dependencies (concat user-emacs-directory "system-dependencies/")) (defconst user-src-packages (concat user-emacs-directory "src-packages/")) ;; Create while cloning repo (defconst user-others-utils (concat user-emacs-directory "others-utils/")) (defconst user-utils (concat user-emacs-directory "my-utils/")) (load custom-file) (unless (boundp 'user-installed-emacs-config?) (mapc #'make-directory `(,user-system-dependencies ,user-src-packages)) ;; Append variable binding of `user-installed-emacs-config?' to file `custom-file' (write-region (format "%s" '(defconst user-installed-emacs-config? t)) nil custom-file t)) ;;; Built-in Primitives (defalias 'yes-or-no-p 'y-or-n-p) (setq inhibit-startup-screen t) (setq default-directory "~/") (setq visible-bell nil) (setq ring-bell-function 'ignore) ;;; Exec Path From Shell (use-package exec-path-from-shell :ensure t :config (exec-path-from-shell-initialize)) ;;; Keychain Environment (use-package keychain-environment :ensure t :config (keychain-refresh-environment)) ;;; Magit (use-package magit :ensure t :bind (("C-c m s" . magit-status) ("C-c m c" . magit-commit) ("C-c m p" . magit-push) ("C-c m S" . magit-stage))) ;;; Utilities (defvar user-others-utils-list (mapcar (lambda (util) (concat user-others-utils util)) '("emacsredux.el" "fuco1.el"))) (unless (file-exists-p (car user-others-utils-list)) (magit-call-git "clone" "https://git.lain.church/zdm/others-utils" (expand-file-name user-others-utils))) (mapc 'load user-others-utils-list) (defalias '/sudo 'emacsredux-sudo-edit) ;;; Winner (use-package winner :config (winner-mode)) ;;; Shell (use-package shell :config (defalias '/shell 'shell)) ;;; Paren (use-package paren :config (show-paren-mode)) ;;; Simple (use-package simple :config (column-number-mode)) ;;; Delete Selection (use-package delsel :config (delete-selection-mode)) ;; Tabs/Spaces (setq-default indent-tabs-mode nil) (setq-default tab-width 4) ;;; Minibuffer Depth (use-package mb-depth :config (setq enable-recursive-minibuffers t) (setq minibuffer-depth-indicate-mode t)) ;;; Aesthetics (mapc (lambda (mode) (funcall mode -1)) '(menu-bar-mode scroll-bar-mode tool-bar-mode)) (use-package doom-themes :ensure t :defer t) (use-package color-theme-sanityinc-tomorrow :ensure t :defer t) (use-package kaolin-themes :ensure t :defer t) (add-to-list 'default-frame-alist '(font . "DejaVu Sans Mono 13")) (setq-default cursor-type 'box) (setq blink-cursor-blinks -1) (setq blink-cursor-interval 0.4) ;;; Electric Pair (use-package electric-pair :defer t :hook (prog-mode . electric-pair-mode)) ;;; Aggressive Indent (use-package aggressive-indent :ensure t :defer t :hook (prog-mode . aggressive-indent-mode)) ;;; Man (use-package man :bind ("C-c c m" . man)) ;;; Link Hint (use-package link-hint :ensure t :defer t) ;;; Ibuffer (use-package ibuffer :init (setq ibuffer-expert t) (setq ibuffer-show-empty-filter-groups nil) (defun user-ibuffer-quit () (interactive) (quit-window t)) :bind (("C-x C-b" . ibuffer) :map ibuffer-mode-map ("q" . user-ibuffer-quit)) :hook (ibuffer-mode . ibuffer-auto-mode) (ibuffer-auto-mode . ibuffer-set-filter-groups-by-mode) :config (fuco1-special-beginning-of-buffer ibuffer (ibuffer-forward-line 1)) (fuco1-special-end-of-buffer ibuffer (ibuffer-backward-line 1))) ;;; Image (use-package image :defer t :init (setq image-animate-loop t)) ;;; Dired (use-package dired+ :load-path user-src-packages :defer t) (unless (require 'dired+ nil 'noerror) (url-copy-file "https://www.emacswiki.org/emacs/download/dired%2b.el" (concat user-src-packages "dired+.el"))) (use-package dired :defer t :hook (dired-mode . dired-hide-details-mode) (dired-mode . auto-revert-mode) :init (setq dired-listing-switches "-la --group-directories-first") (setq dired-recursive-copies 'always) (setq dired-recursive-deletes 'top) (setq global-auto-revert-non-file-buffers t) (setq auto-revert-verbose nil) (setq dired-dwim-target t) :config (fuco1-special-beginning-of-buffer dired (while (not (ignore-errors (dired-get-filename))) (dired-next-line 1))) (fuco1-special-end-of-buffer dired (dired-previous-line 1))) ;;; Doom Modeline (use-package doom-modeline :ensure t :init (doom-modeline-mode 1)) ;;; Ace Link (use-package ace-link :ensure t :defer t :config (ace-link-setup-default)) ;;; Avy (use-package avy :ensure t :defer t :init (setq avy-style 'at-full) :bind (("C-c w" . avy-goto-word-1) ("C-c l" . avy-goto-line))) ;;; Counsel (use-package counsel :ensure t :defer t :init (setq counsel-find-file-at-point t) :bind (("C-s" . counsel-grep-or-swiper) ("M-x" . counsel-M-x) ("M-y" . counsel-yank-pop) ("C-x C-f" . counsel-find-file) ("C-h f" . counsel-describe-function) ("C-h v" . counsel-describe-variable) ("C-c c u" . counsel-unicode-char) ("C-c c o" . counsel-outline)) :config (defalias '/unicode 'counsel-unicode-char)) ;;; Ivy (use-package ivy :ensure t :defer t :init (setq ivy-use-virtual-buffers nil) :config (ivy-mode)) ;;; Swiper (use-package swiper :ensure t :defer t) ;;; Ivy-Avy (use-package ivy-avy :ensure t) ;;; Hydra (use-package hydra :ensure t :defer t) ;; Expand Region (use-package expand-region :ensure t :defer t :bind ("C-=" . er/expand-region)) ;;; Multiple Cursors (use-package multiple-cursors :ensure t :defer t :bind ("C-S-" . mc/add-cursor-on-click)) ;;; Lispy (use-package lispy :ensure t :defer t :hook ((emacs-lisp-mode scheme-mode) . lispy-mode)) ;;; Ace Window (use-package ace-window :ensure :defer t :init (setq aw-scope 'frame) :bind ("C-x o" . ace-window)) ;;; Form Feed (use-package form-feed :ensure t :defer t :hook ((Info-mode org-mode text-mode help-mode) . form-feed-mode)) ;;; Unfill (use-package unfill :ensure t :defer t) ;;; Flyspell (use-package flyspell :defer t :hook ((prog-mode) . flyspell-prog-mode) ((text-mode org-mode) . flyspell-mode)) ;;; PDF Tools (use-package pdf-tools :ensure t :magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install :no-query)) ;;; Geiser (use-package geiser :ensure t :defer t) ;;; Lsp (let ((elixir-directory (expand-file-name (concat user-system-dependencies "elixir-ls/"))) (elixir-zipfile (expand-file-name (concat user-system-dependencies "elixir-ls-1.11.zip")))) (unless (file-directory-p elixir-directory) (url-copy-file "https://github.com/elixir-lsp/elixir-ls/releases/download/v0.6.4/elixir-ls-1.11.zip" elixir-zipfile) (shell-command (concat "unzip " elixir-zipfile " -d " elixir-directory)) (delete-file elixir-zipfile))) (use-package lsp-mode :commands lsp :ensure t :hook elixir-mode :init (add-to-list 'exec-path user-system-dependencies)) ;;; DAP (use-package dap-mode :ensure t :hook ((elixir-mode . dap-mode) (elixir-mode . dap-ui-mode))) ;;; inf-elixir (use-package inf-elixir :after elixir-mode :load-path (lambda () (list (concat user-src-packages "inf-elixir/"))) :bind (:map elixir-mode-map ("C-c i i" . 'inf-elixir) ("C-c i p" . 'inf-elixir-project) ("C-c i l" . 'inf-elixir-send-line) ("C-c i r" . 'inf-elixir-send-region) ("C-c i b" . 'inf-elixir-send-buffer))) (unless (require 'inf-elixir nil 'noerror) (magit-call-git "clone" "https://github.com/J3RN/inf-elixir/" (expand-file-name (concat user-src-packages "inf-elixir/")))) ;;; Elixir (use-package elixir-mode :ensure t :defer t) ;;; Exunit (use-package exunit :ensure t :defer t) ;;; Emacs Upload (use-package emacs-upload :load-path (lambda () (list (concat user-src-packages "emacs-upload/"))) :defer t :bind ("C-c e" . emacs-upload)) (unless (require 'emacs-upload nil 'noerror) (magit-call-git "clone" "https://git.lain.church/zdm/emacs-upload.git" (expand-file-name (concat user-src-packages "emacs-upload/")))) ;;; ERC (use-package erc :defer t :bind (:map erc-mode-map ("C-" . ace-link)) :init (defun user-erc-mpv-url (url &optional new-window) (start-process "mpv" "*mpv*" "mpv" url)) (defun user-erc-feh-url (url &optional new-window) (start-process "feh" "*feh*" "feh" url)) (setq browse-url-browser-function '(("\\(?:flac\\|m\\(?:kv\\|p[34]\\)\\|webm\\|youtube\\)" . user-erc-mpv-url) ("\\(?:JPG\\|PNG\\|\\(?:jp\\|pn\\)g\\)" . user-erc-feh-url) ("." . browse-url-firefox))) (defun user-erc-part-reason (&optional s) (or s (format "(part-or-quit)"))) (setq erc-quit-reason 'user-erc-part-reason) (setq erc-part-reason 'user-erc-part-reason) (setq erc-modules '(pcomplete netsplit fill button match track completion readonly networks ring autojoin noncommands irccontrols move-to-prompt stamp menu list notifications)) (setq erc-timestamp-only-if-changed-flag nil erc-timestamp-format "%I:%M:%S " erc-insert-timestamp-function 'erc-insert-timestamp-left) (setq erc-format-query-as-channel-p t erc-track-priority-faces-only 'all erc-track-faces-priority-list '(erc-error-face erc-current-nick-face erc-keyword-face erc-nick-msg-face erc-direct-msg-face erc-dangerous-host-face erc-notice-face erc-prompt-face) erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE" "324" "329" "332" "333" "353" "477")) (defadvice erc-track-find-face (around erc-track-find-face-promote-query activate) (if (erc-query-buffer-p) (setq ad-return-value (intern "erc-current-nick-face")) ad-do-it)) (defadvice erc-track-modified-channels (around erc-track-modified-channels-promote-query activate) (if (erc-query-buffer-p) (setq erc-track-priority-faces-only 'nil)) ad-do-it (if (erc-query-buffer-p) (setq erc-track-priority-faces-only 'all))) (setq erc-nick "zdm" erc-user-full-name "zdm" erc-system-name "c" erc-email-userid "zdm") (setq erc-disable-ctcp-replies t) (setq erc-fill-prefix nil erc-fill-column 120) (setq erc-flood-protect nil) (setq erc-auto-query 'buffer) (setq erc-prompt ">") (setq erc-format-nick-function 'erc-format-@nick) (setq erc-after-connect nil) (setq erc-interpret-mirc-color t erc-interpret-controls-p t) (setq erc-server-coding-system '(utf-8 . utf-8)) (setq erc-prompt-for-password nil) ;; https://emacs.stackexchange.com/a/39212 (defun basil-default-completion () "Locally revert completion variables to their default values." (setq-local completing-read-function #'completing-read-default) (setq-local completion-in-region-function #'completion--in-region)) ;; https://github.com/mgalgs/.emacs.d/blob/master/init.el#L599-L602 (defun mgalgs-erc-ansi-colors () "For ansi color escape sequences" (ansi-color-apply-on-region (point-min) (point-max))) :hook ((erc-insert-post erc-send-post) . erc-save-buffer-in-logs) ((erc-mode) . basil-default-completion) ((erc-insert-modify) . mgalgs-erc-ansi-colors) :config (load (concat user-utils "erc-faces")) (erc-spelling-mode) (erc-autojoin-mode) (erc-update-modules) (erc-notifications-disable) (add-hook 'focus-in-hook 'erc-notifications-disable) (add-hook 'focus-out-hook 'erc-notifications-enable)) ;;; GPG ;; Use internal pin (setenv "GPG_AGENT_INFO" nil) ;;; Tramp ;; https://emacs.stackexchange.com/a/37855 (setq remote-file-name-inhibit-cache nil) (setq vc-ignore-dir-regexp (format "%s\\|%s" vc-ignore-dir-regexp tramp-file-name-regexp)) ;;; Which Key (use-package which-key :ensure t :init (setq which-key-show-early-on-C-h t) (setq which-key-idle-delay 10000) (setq which-key-idle-secondary-delay 0.05) :config (which-key-mode)) ;;; Slime (use-package slime :ensure t :defer t :config (setq inferior-lisp-program "sbcl")) ;;; Define Word (use-package define-word :ensure t :defer t :bind (("C-c d" . define-word-at-point) ("C-c D" . define-word))) ;;; Prism (use-package prism :ensure t :hook (prog-mode . prism-mode)) ;;; Gnus (use-package gnus :defer t :init (setq user-mail-address "zdm@cock.li" user-full-name "zdm") (setq gnus-select-method '(nnimap "mail.cock.li" (nnimap-address "mail.cock.li") (nnimap-server-port 993) (nnimap-stream ssl))) (setq smtpmail-smtp-server "mail.cock.li" smtpmail-smtp-service 587 smtpmail-stream-type 'starttls send-mail-function 'smtpmail-send-it message-send-mail-function 'smtpmail-send-it))