Skip to content

trevorbernard/emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emacs Configuration

Configuration

This is my emacs, there are many like it, but this one is mine…

Getting Started

The very first thing you need to have installed is a recent version of Emacs. I believe the minimum supported version is Emacs 24 otherwise you’ll have to install package.el and you’re on your own.

I strongly suggest you remap your cap locks key to control to help reduce the onset of Emacs pinky. I even go further and have a new key binding for M-x, so you are hitting Ctrl instead of Alt.

You will need the following already installed for this configuration to run correctly.

Install the Fira Code Retina font because it’s beautiful and makes for a wonderful font. You will need ispell installed in order to user Flymake mode. Clojure mode requires leiningen.

Emacs Initialization

I use melpa and melpa stable for my packages.

(require 'package)

(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)

I don’t like my cider to be bleeding edge since it’s caused compatability problems in the past so pin it to melpa-stable.

(add-to-list 'package-pinned-packages '(cider . "melpa-stable") t)

Install my packages if they aren’t installed.

(package-initialize)

(when (not package-archive-contents)
  (package-refresh-contents))

(defvar my-packages '(ag
                      bnf-mode
                      cider
                      clj-refactor
                      clojure-mode
                      csv-mode
                      company
                      dockerfile-mode
                      eclim
                      eglot
                      flycheck-plantuml
                      gradle-mode
                      htmlize
                      just-mode
                      lsp-mode
                      lsp-ui
                      magit
                      markdown-mode
                      nix-mode
                      nixpkgs-fmt
                      ox-gfm
                      paredit
                      plantuml-mode
                      projectile
                      protobuf-mode
                      rainbow-delimiters
                      rustic
                      string-inflection
                      terraform-mode
                      timu-spacegrey-theme
                      tuareg
                      yaml-mode)
  "A list of packages to ensure are installed at launch.")

(dolist (p my-packages)
  (when (not (package-installed-p p))
    (package-install p)))

I like to have my Emacs clean, chrisp and minimal. Removing the menu bar, tool bar, and scroll bar frees some space and it helps remove dependency on the mouse. Protip: Learn the Emacs navigation key strokes until they are second nature. You can thank me later.

(setq inhibit-startup-message t)

;; (load-theme 'dracula t)
(load-theme 'timu-spacegrey t)

(dolist (mode '(menu-bar-mode tool-bar-mode scroll-bar-mode))
  (when (fboundp mode) (funcall mode -1)))

(when window-system
;;  (add-to-list 'default-frame-alist '(alpha . (95 . 50)))
;;  (set-frame-parameter (selected-frame) 'alpha '(95 . 50))
  (set-frame-font "Fira Code Retina 18" nil t))

Personal

Dats me.

(setq user-full-name "Trevor Bernard"
      user-mail-address "trevor@bernard.gg")

Key Bindings

Ignore minimize functionality when you’re in a GUI because it’s very annoying to accidently minimize your window.

(when window-system
  (global-set-key "\C-z" 'ignore)
  (global-set-key "\C-x\C-z" 'ignore))

Invoke M-x without the Alt key

M-x is one of the most wildly used key combinations in Emacs but it’s also the most annoying. You have to scrunch your left thumb and fore finger in the most uncomfortable RSI inducing way.

I choose to rebind M-x to C-x C-m because of an article Steve Yegge wrote called: Effective Emacs. This allows you to keep your fingers on the home row if you have caps lock mapped to control. With some practice, it will become intuitive.

(global-set-key "\C-x\C-m" 'execute-extended-command)
(global-set-key "\C-c\C-m" 'execute-extended-command)

Preferences

Global Preferences

(add-to-list 'load-path "~/.emacs.d/lisp/")

(set-fringe-mode 10) ; breathing room
(setq make-backup-files nil) ; stop creating backup~ files
(setq auto-save-default nil) ; stop creating #autosave# files
(setq interprogram-paste-function 'x-selection-value) ;
(global-auto-revert-mode t) ; Auto revert buffers
(ido-mode 1)
(column-number-mode 1) ; Show column number
(delete-selection-mode 1) ; Allow delete of selection
(fset 'yes-or-no-p 'y-or-n-p) ; Shorten confirmation message
(global-font-lock-mode 1) ; Syntax Highlighting
(show-paren-mode 1) ; Highlight parenthesis
;; Highlight selected Regions
(transient-mark-mode 1)
;; Make pgup/dn remember current line
(setq scroll-preserve-screen-position t)
(add-hook 'prog-mode-hook 'display-line-numbers-mode)

Use spaces in favour of tabs because they are evil. But when there are tabs show them as 8 spaces.

(setq-default indent-tabs-mode nil)
(setq-default c-basic-offset 4)
(setq-default tab-width 8)

Limit the default fill mode to 80 characters

(setq-default set-fill-column 80)
(setq-default truncate-lines nil)

Ignore the stupid ring bell feature.

(setq ring-bell-function 'ignore)

Allow functions without issuing warnings

(put 'downcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'upcase-region 'disabled nil)

Mac specific configuration

(defun set-exec-path-from-shell-PATH ()
  (let ((path-from-shell (shell-command-to-string "$SHELL -i -c 'echo $PATH'")))
    (setenv "PATH" path-from-shell)
    (setq exec-path (split-string path-from-shell path-separator))))

(defun my-mac-config ()
  ;; Mac's ls doesn't support --dired
  (setq dired-use-ls-dired nil)

  ;; setup the correct shell path
  (set-exec-path-from-shell-PATH)

  ;; Move to trash when deleting stuff
  (setq delete-by-moving-to-trash t
        trash-directory "~/.Trash/emacs")

  ;; Don't open files from the workspace in a new frame
  (setq ns-pop-up-frames nil)

  ;; Use aspell for spell checking: brew install aspell --lang=en
  (setq ispell-program-name "/opt/homebrew/bin/aspell")

  ;; Open up links in Google Chrome
  (setq browse-url-browser-function 'browse-url-default-macosx-browser))

(when (equal system-type 'darwin)
  (my-mac-config))

Programming Languages

Bind projectile to C-c p and enable by default.

Projectile Mode

(setq projectile-project-search-path '("~/p/"))
(setq projectile-keymap-prefix (kbd "C-c p"))
(projectile-mode +1)

Magit

C-c is reserved for the user. Add a more friendly binding for magit-file-dispatch

(global-set-key (kbd "C-c g") 'magit-file-dispatch)

Clojure

(require 'cider)
(require 'clojure-mode)
(require 'company)

(setq nrepl-log-messages t)
(setq cider-repl-use-clojure-font-lock t)
(setq cider-repl-display-help-banner nil)

(defun my-cider-repl-mode-hook ()
  (company-mode 1)
  (paredit-mode 1)
  (rainbow-delimiters-mode 1))

(defun my-cider-mode-hook ()
  (company-mode 1)
  (eldoc-mode 1))

(defun my-clojure-mode-hook ()
  (setq show-trailing-whitespace 1)
  (setq clojure-align-forms-automatically t)
  (clj-refactor-mode 1)
  (rainbow-delimiters-mode 1)
  (linum-mode t)
  (paredit-mode 1)
  (subword-mode t)
  (eldoc-add-command 'paredit-backward-delete 'paredit-close-round))

(add-hook 'cider-repl-mode-hook 'my-cider-repl-mode-hook)
(add-hook 'cider-mode-hook 'my-cider-mode-hook)
(add-hook 'clojure-mode-hook 'my-clojure-mode-hook)

I have long since used this key binding to jack into a repl. My fingers are programmed this way.

(global-set-key (kbd "C-c C-j") 'cider-jack-in)

When you hit f3 at the end of the sexp in Clojure, it will copy and evaluate the function into the current repl. I no longer use this function but it might be useful to someone eventually.

(defun my-last-expression ()
  "Return the last sexp."
  (buffer-substring-no-properties
   (save-excursion (backward-sexp) (point))
   (point)))

(defun cider-execute-in-current-repl (expr)
  (if (not (get-buffer (cider-current-connection)))
      (message "No active nREPL connection.")
    (progn
      (set-buffer (cider-current-repl))
      (goto-char (point-max))
      (insert expr)
      (cider-repl-return))))

(defun cider-eval-expression-at-point-in-repl ()
  (interactive)
  (let ((form (my-last-expression)))
    ;; Eat white
    (while (string-match "\\`\s+\\|\n+\\'" form)
      (setq form (replace-match "" t t form)))
    (cider-execute-in-current-repl form)))

(eval-after-load 'cider-repl-mode-hook
  '(local-set-key '[f3] 'cider-eval-expression-at-point-in-repl))

ClojureScript

This is required for re-frame cider intergration.

(setq cider-cljs-lein-repl
      "(do (require 'figwheel-sidecar.repl-api)
           (figwheel-sidecar.repl-api/start-figwheel!)
           (figwheel-sidecar.repl-api/cljs-repl))")

Elisp

(defun my-emacs-lisp-mode-hook ()
  (paredit-mode 1)
  (eldoc-mode 1))

(add-hook 'emacs-lisp-mode-hook 'my-emacs-lisp-mode-hook)

Paredit

Some handy dandy paredit shortcuts

On mac ^-left and ^-right are bought to Misson Control. Go to System Preferences > Keyboard > Shortcuts > Mission Control and change the settings for “Move left a space” and “Move right a space” or disable them completely.

(eval-after-load 'paredit
  '(progn
     (define-key paredit-mode-map (kbd "C-<right>") 'paredit-forward-slurp-sexp)
     (define-key paredit-mode-map (kbd "C-<left>") 'paredit-forward-barf-sexp)
     (define-key paredit-mode-map (kbd "C-<backspace>") 'paredit-backward-kill-word)))

Org Mode

I almost exclusively use C-j in place of hitting the enter key. The problem is that it’s bound to org-return-indent function. This is very annoying in when you are in org-mode. So instead of trying to remap my brain, I’ll remap it to newline.

(global-set-key (kbd "C-c l") #'org-store-link)
(global-set-key (kbd "C-c a") #'org-agenda)
(global-set-key (kbd "C-c c") #'org-capture)

(defun my-org-mode-hook ()
  (turn-on-auto-fill)
  (define-key org-mode-map (kbd "C-j") 'org-return)
  (org-babel-do-load-languages 
   'org-babel-load-languages '((clojure . t)
                               (plantuml . t)
                               (rust . t)
                               (shell . t))))
(add-hook 'org-mode-hook 'my-org-mode-hook)

Exporting to PDF

In order to export to PDF, I choose to use basictex and install packages only when they are missing.

brew reinstall --cask basictex
sudo tlmgr update --self
sudo tlmgr install wrapfig
sudo tlmgr install capt-of

JavaScript

(defun my-js-mode-hook ()
  (setq js-indent-level 2))

(add-hook 'js-mode-hook 'my-js-mode-hook)

CSS

(autoload 'css-mode "css-mode" nil t)

(defun my-css-mode-hook ()
  (setq css-indent-level 2)
  (setq css-indent-offset 2))

(add-hook 'css-mode-hook 'my-css-mode-hook)

Markdown

(autoload 'markdown-mode "markdown-mode" "Major mode for editing Markdown files" t)

;; Double click on mac mouse trackpad
(eval-after-load "flyspell"
  '(progn
     (define-key flyspell-mouse-map [down-mouse-3] #'flyspell-correct-word)
     (define-key flyspell-mouse-map [mouse-3] #'undefined)))

(add-to-list 'auto-mode-alist '("\\.text\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))

(defun my-markdown-hook ()
  (auto-fill-mode t)
  (flyspell-mode t))

(add-hook 'markdown-mode-hook 'my-markdown-hook)

Git

Use diff-mode when editing a git commit message

(add-to-list 'auto-mode-alist '("COMMIT_EDITMSG$" . diff-mode))

Terminal Emulation

Calling M-x ansi-term will prompt you for which shell you want to spawn. TODO. Find a keybinding

(defun my/term ()
  (interactive)
  (term "/bin/zsh"))

Rust

(require 'eglot)

(defun my-rust-mode-hook ()
  (setq rustic-cargo-build-arguments "--release")
  (setq rustic-default-clippy-arguments "--all-targets --all-features -- -D warnings")
  (yas-minor-mode))

(add-hook 'rust-mode-hook 'my-rust-mode-hook)
(add-hook 'rust-mode-hook 'eglot-ensure)

(setq rustic-compile-command "cargo b --release")

ELISP

(defun my-ielm-mode-hook ()
  (paredit-mode 1)
  (rainbow-delimiters-mode 1)
  (define-key ielm-map (kbd "C-m") 'ielm-return)
  (define-key ielm-map (kbd "<return>") 'ielm-return))

(add-hook 'ielm-mode-hook 'my-ielm-mode-hook)

OCaml

(defun my-ocaml-mode-hook ())

(add-hook 'tuareg-mode-hook 'my-ocaml-mode-hook)

Nix

(defun my-nix-mode-hook ()
  (nixpkgs-fmt-on-save-mode)
  (define-key 'nix-mode-map (kbd "C-c C-f") 'nixpkgs-fmt))

(add-hook 'nix-mode-hook 'my-nix-mode-hook)

About

This is my emacs, there are many like it, but this one is mine...

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published