Use use-package
for package management.
(setq package-archives
'(("gnu" . "https://elpa.gnu.org/packages/")
("melpa-stable" . "https://stable.melpa.org/packages/")
("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")))
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(setq use-package-always-ensure t)
(use-package delight :ensure t)
(use-package diminish :ensure t)
(use-package use-package-ensure-system-package :ensure t)
Disable that annoying bell sound.
(setq ring-bell-function (lambda () (message "*beep*")))
Better GC values.
(setq gc-cons-threshold 10000000)
(let ((normal-gc-cons-threshold (* 20 1024 1024))
(init-gc-cons-threshold (* 128 1024 1024)))
(setq gc-cons-threshold init-gc-cons-threshold)
(add-hook 'after-init-hook
(lambda ()
(setq gc-cons-threshold normal-gc-cons-threshold))))
Better M-x menu.
(use-package smex)
Better buffer navigation and manipulation. Replace default buffer UI with ibuffer.
(use-package ibuffer
:defer t
:bind ("C-x C-b" . ibuffer)
:custom
(defalias 'list-buffers 'ibuffer))
Avoid appending UI customizations to init.el
.
(setq-default custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file t))
I work in UTF-8.
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
Default settings for Emacs.
(setq
ad-redefinition-action 'accept ; Silence warnings for redefinition
cursor-in-non-selected-windows t ; Hide the cursor in inactive windows
display-time-default-load-average nil ; Don't display load average
fill-column 80 ; Set width for automatic line breaks
help-window-select t ; Focus new help windows when opened
inhibit-startup-screen t ; Disable start-up screen
initial-scratch-message "" ; Empty the initial *scratch* buffer
load-prefer-newer t ; Prefers the newest version of a file
scroll-margin 8 ; smooth scroll
redisplay-dont-pause t
scroll-preserve-screen-position 1
scroll-conservatively 1000
scroll-step 1
select-enable-clipboard t ; Merge system's and Emacs' clipboard
tab-width 4 ; Set width for tabs
use-package-always-ensure t ; Avoid the :ensure keyword for each package
user-full-name "chris etheridge" ; Set the full name of the current user
user-mail-address "[email protected]" ; Set the email address of the current user
ffap-machine-p-known 'reject ; don't try ping domains
delete-by-moving-to-trash t ; delete by moving to trash
show-trailing-whitespace t ; always show trailing whitespace
vc-follow-symlinks t
disabled-command-function nil
indent-tabs-mode nil
tab-always-indent 'complete) ; Always follow the symlinks
(cd "~/") ; Move to the user directory
(column-number-mode 1) ; Show the column number
(global-linum-mode 1) ; Enable line numbers
(display-time-mode 1) ; Enable time in the mode-line
(fset 'yes-or-no-p 'y-or-n-p) ; Replace yes/no prompts with y/n
(show-paren-mode 1) ; Show the parent
(delete-selection-mode 1) ; Replace selection on paste
(global-subword-mode 1) ; Move through camel case words
(electric-pair-mode 1) ; match parenthesis
(global-auto-revert-mode 1) ; refresh buffers
Disable that annoying bell sound.
(setq ring-bell-function (lambda () (message "*beep*")))
Always :ensure
packages.
(setq use-package-always-ensure t)
Use saveplace to save place in file after closing.
(use-package saveplace
:config
(setq save-place-file (concat user-emacs-directory "places")))
Clean whitespace upon saving, and disable backups, change autosave file location.
(setq-default backup-inhibited t)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(setq auto-save-file-name-transforms
`((".*" "~/.emacs-saves/" t)))
(setenv "PATH" (concat "/usr/local/bin:" (getenv "PATH")))
(add-to-list 'exec-path "/usr/local/bin")
Make Emacs read vars from the environment.
(use-package exec-path-from-shell
:config
(exec-path-from-shell-initialize))
Better M-x menu.
(use-package smex)
Better buffer navigation and manipulation. Replace default buffer UI with ibuffer.
(use-package ibuffer
:defer t
:bind ("C-x C-b" . ibuffer)
:custom
(defalias 'list-buffers 'ibuffer))
Track key frequency.
(use-package keyfreq
:bind ("M-f" . keyfreq-show)
:custom
(keyfreq-mode 1)
(keyfreq-autosave-mode 1))
Magit for git management.
(use-package magit
:defer t
:bind ("C-c g" . magit-status)
:delight
(magit-autro-revert-mode)
(auto-revert-mode))
Show Git changes in the fringe of Emacs. https://github.com/syohex/emacs-git-gutter-fringe
(use-package git-gutter-fringe
:defer t
:custom
(git-gutter-mode))
Show historical git versions of files.
(use-package git-timemachine
:config
(setq git-timemachine-abbreviation-length 6))
(use-package evil-leader)
(use-package evil-magit)
Avoid appending UI customizations to init.el
.
(setq-default custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file t))
(load-theme 'poet-monochrome t)
(set-frame-font "Hack 12" nil t)
;; override poet theme font settings
(set-face-attribute 'default nil :family "Hack" :height 120)
(set-face-attribute 'fixed-pitch nil :family "Hack")
(set-face-attribute 'variable-pitch nil :family "Hack")
Add line, column, and file size to modeline.
(line-number-mode t)
(column-number-mode t)
(size-indication-mode t)
Use telephone line for the modeline.
(use-package doom-modeline
:ensure t
:defer t
:hook (after-init . doom-modeline-init)
:config
;; How tall the mode-line should be (only respected in GUI Emacs).
(setq doom-modeline-height 30)
;; How wide the mode-line bar should be (only respected in GUI Emacs).
(setq doom-modeline-bar-width 3)
;; Whether show `all-the-icons' or not (if nil nothing will be showed).
;; The icons may not be showed correctly on Windows. Disable to make it work.
(setq doom-modeline-icon nil)
;; Determines the style used by `doom-modeline-buffer-file-name'.
;;
;; Given ~/Projects/FOSS/emacs/lisp/comint.el
;; truncate-upto-project => ~/P/F/emacs/lisp/comint.el
;; truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el
;; truncate-with-project => emacs/l/comint.el
;; truncate-except-project => ~/P/F/emacs/l/comint.el
;; truncate-upto-root => ~/P/F/e/lisp/comint.el
;; truncate-all => ~/P/F/e/l/comint.el
;; relative-from-project => emacs/lisp/comint.el
;; relative-to-project => lisp/comint.el
;; file-name => comint.el
;; buffer-name => comint.el<2> (uniquify buffer name)
;;
;; If you are expereicing the laggy issue, especially while editing remote files
;; with tramp, please try `file-name' style.
;; Please refer to https://github.com/bbatsov/projectile/issues/657.
(setq doom-modeline-buffer-file-name-style 'truncate-upto-root)
;; Whether show the icon for major mode. It should respect `doom-modeline-icon'.
(setq doom-modeline-major-mode-icon nil)
;; Whether display minor modes or not. Non-nil to display in mode-line.
(setq doom-modeline-minor-modes nil))
(use-package hl-todo
:ensure t
:hook (prog-mode . hl-todo-mode))
Turn off GUI elements.
(when window-system
(menu-bar-mode -1) ; Disable the menu bar
(scroll-bar-mode -1) ; Disable the scroll bar
(tool-bar-mode -1) ; Disable the tool bar
(tooltip-mode -1)) ; Disable the tooltips
Smooth scrolling.
(use-package smooth-scrolling
:config
(smooth-scrolling-mode 1)
(setq smooth-scroll-margin 18))
Ivy, Swiper, and Counsel for command completion UI (like Helm) https://github.com/abo-abo/swiper
(use-package counsel
:after ivy
:diminish
:config (counsel-mode)
:bind (("s-g" . counsel-ag)))
(use-package ivy
:defer 0.1
:diminish
:bind (("C-c C-r" . ivy-resume)
("C-x B" . ivy-switch-buffer-other-window))
:custom
(ivy-count-format "(%d/%d) ")
(ivy-use-virtual-buffers t)
:config (ivy-mode)
(setq ivy-initial-inputs-alist nil))
(use-package ivy-pass
:after ivy
:commands ivy-pass)
(use-package ivy-rich
:after ivy
:custom
(ivy-virtual-abbreviate 'full
ivy-rich-switch-buffer-align-virtual-buffer t
ivy-rich-path-style 'abbrev))
(use-package swiper
:after ivy
:bind (("C-s" . swiper)))
Use a dashboard-like start page. https://github.com/rakanalh/emacs-dashboard
(use-package dashboard
:preface
(defun my/dashboard-banner ()
"Set a dashboard banner including information on package initialization
time and garbage collections."
(setq dashboard-banner-logo-title
(format "ready in %.2f sec with %d gc"
(float-time (time-subtract after-init-time before-init-time)) gcs-done)))
:init
(add-hook 'after-init-hook 'dashboard-refresh-buffer)
(add-hook 'dashboard-mode-hook 'my/dashboard-banner)
:custom
(dashboard-startup-banner 'logo)
:config
(setq dashboard-items '((recents . 5)
(bookmarks . 5)
(projects . 5)
(agenda . 5)
(registers . 5)))
(dashboard-setup-startup-hook))
Use winner to move around windows.
(use-package winner
:ensure t
:init (winner-mode 1))
Use iedit for multiple cursor editing.
(use-package iedit)
Undo tree
(use-package undo-tree
:diminish
:bind
("C--" . undo-tree-redo)
:init
(progn
(global-undo-tree-mode 1)
(defalias 'redo 'undo-tree-redo)
(global-set-key (kbd "s-z") 'undo)
(global-set-key (kbd "s-Z") 'redo))
:custom
(undo-tree-visualizer-timestamps t)
(undo-tree-visualizer-diff t))
Which key to show keybindings
(use-package which-key
:diminish
:config (which-key-mode))
Visually browse the kill ring.
(use-package browse-kill-ring
:bind
("C-c C-k" . browse-kill-ring))
Highlight color values as their color
(use-package rainbow-mode
:defer 2
:hook (prog-mode))
Highlight the same symbols.
(use-package highlight-symbol
:custom
(highlight-symbol-mode))
Use company for auto completion.
(use-package company
:defer 2
:diminish
:config
(setq company-global-modes '(not term-mode))
(setq company-minimum-prefix-length 2
company-selection-wrap-around t
company-show-numbers t
company-tooltip-align-annotations t
company-require-match nil
company-dabbrev-downcase nil
company-dabbrev-ignore-case nil)
(setq company-transformers '(company-sort-by-occurrence))
(use-package company-quickhelp
:config
(setq company-quickhelp-delay nil)
(company-quickhelp-mode 1))
:custom
(company-begin-commands '(self-insert-command))
(company-idle-delay .1)
(company-minimum-prefix-length 2)
(company-show-numbers t)
(company-tooltip-align-annotations 't)
(global-company-mode t))
Use Projectile for project management.
(use-package ag)
(use-package projectile
:defer 1
:init
(setq projectile-keymap-prefix (kbd "C-c p"))
:custom
(projectile-cache-file (expand-file-name ".projectile-cache" user-emacs-directory))
(projectile-completion-system 'ivy)
(projectile-enable-caching t)
(projectile-known-projects-file (expand-file-name
".projectile-bookmarks" user-emacs-directory))
(projectile-mode-line '(:eval (projectile-project-name)))
:config
(setq projectile-globally-ignored-directories
(cl-union projectile-globally-ignored-directories
'(".git"
".cljs_rhino_repl"
".svn"
"out"
"node_modules"
"resources/public/js/compiled")))
(setq projectile-globally-ignored-files
(cl-union projectile-globally-ignored-files
'(".DS_Store"
".lein-repl-history"
"*.gz"
"*.pyc"
"*.png"
"*.jpg"
"*.jar"
"*.retry"
"*.svg"
"*.tar.gz"
"*.tgz"
"*.zip")))
(setq projectile-mode-line '(:eval (format " [%s] " (projectile-project-name))))
(projectile-global-mode)
:bind)
Use perspective for different project contexts.
(use-package perspective
:ensure t
:bind ("C-x x x" . persp-switch-last)
:init (persp-mode +1)
(use-package persp-projectile
:ensure t
:bind ("C-x x P" . projectile-persp-switch-project))
:config
(setq persp-interactive-completion-function #'ido-completing-read)
(persp-turn-off-modestring))
(use-package flycheck
:defer 2
:diminish
:init (global-flycheck-mode))
Fly spell for spelling.
(use-package flyspell
:defer 1
:custom
(flyspell-abbrev-p t)
(flyspell-issue-message-flag nil)
(flyspell-issue-welcome-flag nil)
(flyspell-mode 1))
(use-package flyspell-correct-ivy
:after flyspell
:bind (:map flyspell-mode-map
("C-;" . flyspell-correct-word-generic))
:custom (flyspell-correct-interface 'flyspell-correct-ivy))
(use-package ispell
:custom
(ispell-silently-savep t))
Set aspell path.
(setq ispell-program-name "/usr/local/bin/aspell")
(use-package paradox
:defer 2
:custom
(paradox-column-width-package 27)
(paradox-column-width-version 13)
(paradox-execute-asynchronously t)
(paradox-hide-wiki-packages t)
:config
(paradox-enable)
(remove-hook 'paradox-after-execute-functions #'paradox--report-buffer-print))
(use-package yasnippet
:ensure t
:config (progn (setq yas-snippet-dirs '("~/.emacs.d/snippets"))
(add-hook 'term-mode-hook (lambda() (setq yas-dont-activate t)))
(yas-global-mode 1)))
(use-package yasnippet-snippets
:after yasnippet
:config (yasnippet-snippets-initialize))
(use-package ivy-yasnippet :after yasnippet)
Paredit and paxedit for sexp editing.
(use-package paxedit
:delight
:hook
((org-mode
emacs-lisp-mode
clojure-mode
cider-repl-mode) . paxedit-mode)
:bind (:map paxedit-mode-map
("M-t" . 'paxedit-transpose-forward)
("C-M-t" . 'paxedit-transpose-backward)))
(use-package paredit
:delight
:hook ((org-mode
emacs-lisp-mode
clojure-mode
cider-repl-mode
racket-mode) . paredit-mode)
:bind (:map paredit-mode-map
("M-[" . paredit-wrap-square)
("M-{" . paredit-wrap-curly)))
Show different colors between delimiter levels.
(use-package rainbow-delimiters
:defer 1
:hook (prog-mode . rainbow-delimiters-mode))
(use-package elisp-mode
:ensure nil
:delight emacs-lisp-mode "ξ")
(use-package clojure-mode
:config
(require 'flycheck-clj-kondo)
(setq clojure-align-forms-automatically t)
(define-clojure-indent
;; Compojure
(GET 'defun)
(POST 'defun)
(context 'defun)
(tufte/p 'defun)
(tufte/profile 'defun)
(cj/GET 'defun)
(cj/POST 'defun )
(cj/context 'defun))
:bind
("C-c C-q" . cider-quit))
Add an IDE-like exeperience to Emacs, primarily interaction a Clojure REPL. https://github.com/clojure-emacs/cider
(use-package cider
:custom
(cider-auto-test-mode 1)
(global-set-key (kbd "C-c r") 'cider-repl-reset)
:bind
(("C-c M-s" . cider-connect-clojurescript)
("C-x C-r" . cider-inspect-last-result)
("C-x C-s" . cider-inspect-last-sexp))
:hook
(cider-mode-hook . eldoc-mode)
:config
(setq
nrepl-log-messges t
cider-use-fringe-indicators nil ;
cider-prompt-for-symbol nil ; Don't prompt for symbol for cider doc
cider-repl-pop-to-buffer-on-connect nil
cider-repl-display-in-current-window t ; open repl buffer in current window
cider-show-error-buffer t ; don't show error buffer automatically
cider-auto-select-error-buffer nil ; don't switch to error buffer on error
cider-save-file-on-load t ; save file on prompt when evaling
cider-repl-history-file (concat user-emacs-directory "cider-history")
cider-repl-use-clojure-font-lock t ; nicer repl output
cider-font-lock-dynamically t ; font-lock as much as possible
cider-font-lock-reader-conditionals nil ; Disable font-locking for symbols in cljc files
cider-repl-wrap-history t
cider-repl-history-size 3000
))
(use-package cider-eval-sexp-fu)
Refactor Clojure code. https://github.com/clojure-emacs/clj-refactor.el
(use-package clj-refactor
:after (clojure-mode yasnippet)
:config
(cljr-add-keybindings-with-prefix "C-c C-r")
:hook
(clj-refactor-mode . yas-minor-mode)
(clojure-mode . clj-refactor-mode))
Use flycheck-joker for linting.
;; (use-package flycheck-joker)
(use-package flycheck-clj-kondo
:ensure t)
(use-package css-mode
:custom (css-indent-offset 2))
(use-package emmet-mode
:defer 6
:hook (sgml-mode css-mode web-mode))
(use-package less-css-mode
:mode "\\.less\\'"
:interpreter ("less" . less-css-mode))
(use-package scss-mode :mode "\\.scss\\'")
(use-package markdown-mode
:delight markdown-mode "μ"
:mode ("INSTALL\\'"
"CONTRIBUTORS\\'"
"LICENSE\\'"
"README\\'"
"\\.markdown\\'"
"\\.md\\'"))
(defun find-config ()
"Edit config.org"
(interactive)
(find-file "~/.emacs.d/config.org"))
(global-set-key (kbd "C-c I") 'find-config)
Define a function that asynchrously compiles the config.org file, into the config file that Emacs uses. Copied from from: https://raw.githubusercontent.com/rememberYou/.emacs.d/e96fec91103524761b9e6bd66811121106db1639/config.org
(use-package async)
(defvar *config-file* (expand-file-name "config.org" user-emacs-directory)
"The configuration file.")
(defvar *config-last-change* (nth 5 (file-attributes *config-file*))
"Last modification time of the configuration file.")
(defvar *show-async-tangle-results* nil
"Keeps *emacs* async buffers around for later inspection.")
(defun my/config-updated ()
"Checks if the configuration file has been updated since the last time."
(time-less-p *config-last-change*
(nth 5 (file-attributes *config-file*))))
(defun my/config-tangle ()
"Tangles the org file asynchronously."
(when (my/config-updated)
(setq *config-last-change*
(nth 5 (file-attributes *config-file*)))
(my/async-babel-tangle *config-file*)))
(my/config-tangle)
(defun my/async-babel-tangle (org-file)
"Tangles the org file asynchronously."
(let ((init-tangle-start-time (current-time))
(file (buffer-file-name))
(async-quiet-switch "-q"))
(async-start
`(lambda ()
(require 'org)
(org-babel-tangle-file ,org-file)))
(unless *show-async-tangle-results*
`(lambda (result)
(if result
(message "SUCCESS: %s successfully tangled (%.2fs)."
,org-file
(float-time (time-subtract (current-time)
',init-tangle-start-time)))
(message "ERROR: %s as tangle failed." ,org-file))))))
(use-package org
:init
(add-hook 'org-mode-hook 'visual-line-mode)
(add-hook 'org-mode-hook 'org-indent-mode)
(add-hook 'org-mode-hook 'flyspell-mode)
:diminish visual-line-mode
:diminish org-indent-mode
:ensure org-plus-contrib
:hook
((before-save . (lambda ()
(interactive)
(org-table-recalculate-buffer-tables)))
(after-save . my/config-tangle))
:config
(setq
org-src-fontify-natively t
org-src-tab-acts-natively t
org-confirm-babel-evaluate nil
org-ellipsis " ... "
org-startup-truncated nil
org-export-with-smart-quotes nil
org-replace-disputed-keys t)
(add-to-list 'org-structure-template-alist
'("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC"))
(use-package org-bullets
:defer t
:init
(add-hook 'org-mode-hook
(lambda ()
(org-bullets-mode t)))))
(use-package org-indent :after org :ensure nil :diminish)