From 2ece7032558cd0be673d65237a01c5e6ffe625f1 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 19 Nov 2022 15:21:44 +0000 Subject: Move to a GNU Stow config --- emacs/.config/emacs/init.el | 19 + emacs/.config/emacs/loader.org | 1268 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1287 insertions(+) create mode 100644 emacs/.config/emacs/init.el create mode 100644 emacs/.config/emacs/loader.org (limited to 'emacs/.config/emacs') diff --git a/emacs/.config/emacs/init.el b/emacs/.config/emacs/init.el new file mode 100644 index 0000000..8029cb2 --- /dev/null +++ b/emacs/.config/emacs/init.el @@ -0,0 +1,19 @@ +(setq init-dir (file-name-directory (or load-file-name (buffer-file-name)))) + +(require 'package) + +(defvar gnu '("gnu" . "https://elpa.gnu.org/packages/")) +(defvar melpa '("melpa" . "https://melpa.org/packages/")) +(defvar melpa-stable '("melpa-stable" . "https://stable.melpa.org/packages/")) +(defvar org-elpa '("org" . "https://orgmode.org/elpa/")) + +(setq package-archives nil) +(add-to-list 'package-archives melpa-stable t) +(add-to-list 'package-archives melpa t) +(add-to-list 'package-archives gnu t) +(add-to-list 'package-archives org-elpa t) + +(setq package-enable-at-startup nil) +(package-initialize) + +(org-babel-load-file (expand-file-name "loader.org" init-dir)) diff --git a/emacs/.config/emacs/loader.org b/emacs/.config/emacs/loader.org new file mode 100644 index 0000000..b885599 --- /dev/null +++ b/emacs/.config/emacs/loader.org @@ -0,0 +1,1268 @@ +#+TITLE: GNU Emacs Configuration +#+DATE: <2017-08-11 Fri> +#+AUTHOR: Yann Herklotz Grave + +* Introduction +This is my GNU Emacs Configuration. + +It is written in a literate style using orgmode tangling to generate the actual +configuration file. This can be done by adding the following line to the +~init.el~ file. + +#+BEGIN_SRC + (setq init-dir (file-name-directory (or load-file-name (buffer-file-name)))) + (org-babel-load-file (expand-file-name "loader.org" init-dir)) +#+END_SRC + +It has support for many programming languages such as C++, Haskell and +Clojure. The configurations for the different languages can be found in the +[[#Programming][Programming]] section. It also supports academic writing with org mode using the +amazing [[https://github.com/jkitchin/org-ref][org-ref]] package to add citations to the LaTeX output. The configuration +for that can be found in the [[#Writing][Writing]] section. + +#+BEGIN_SRC emacs-lisp + (setq user-full-name "Yann Herklotz") + (setq user-mail-address "yann@yannherklotz.com") +#+END_SRC + +* Setup + +Set path so that it picks up some executables that I use. This is done because +when emacs is started as a server, the PATH is not set correctly, so it has to +be manually set inside emacs. + +#+BEGIN_SRC emacs-lisp + (setenv "PATH" + (concat + "/home/ymherklotz/.local/bin" ":" + "/home/ymherklotz/.yarn/bin" ":" + "/usr/bin/vendor_perl" ":" + "/home/ymherklotz/.nix-profile/bin" ":" + (getenv "PATH"))) + (setq exec-path (append + '("/home/ymherklotz/.local/bin" + "/home/ymherklotz/.yarn/bin" + "/home/ymherklotz/.nix-profile/bin") + exec-path)) +#+END_SRC + +Define a function to load a user file whenever I want to add configurations that +are not pushed as part of this configuration file. This includes a private file +containing email configurations for [[https://www.emacswiki.org/emacs/mu4e][mu4e]]. In this case, ~user-init-dir~ is used +to find the current init directory that Emacs is using and ~load-user-file~ can +be used to load any file in that directory. + +#+BEGIN_SRC emacs-lisp + (defconst user-init-dir + (cond ((boundp 'user-emacs-directory) + user-emacs-directory) + ((boundp 'user-init-directory) + user-init-directory) + (t "~/.emacs.d/"))) + + (defun load-user-file (file) + (interactive "f") + "Load a file in current user's configuration directory" + (load-file (expand-file-name file user-init-dir))) + + (setq load-path + (cons (expand-file-name "~/.emacs.d/modes") load-path)) +#+END_SRC + +** Repositories +Defining all the package repositories that are going to be used. + +- ~gnu~ :: The default package repository for emacs +- ~melpa~ :: Contains a lot of additional packages for emacs that are made by + the community. +- ~melpa-stable~ :: The stable melpa repository that only contains that full + versions for packages. This repository will be used for + packages that maybe get updated often, so that they do not + break the config. +- ~org~ :: org package repository that contains many packages to extend org-mode. + +Use ~use-package~ to manage other packages, and improve load times. + +#+BEGIN_SRC emacs-lisp + (require 'use-package) + + (setq use-package-always-ensure t) +#+END_SRC + +** GC Threshold + +Threshold for faster startup. This should increase the garbage collector's +threshold at which it will start cleaning, so that it is not triggered during +startup. + +#+BEGIN_SRC emacs-lisp + (setq gc-cons-threshold (* 1024 1024 1024)) +#+END_SRC + +** General Configuration +*** Editor settings + +Editor specific options such as adding line numbers. + +Disable UI that starts when starting emacs and also set the y or n instead of +yes or no. Also stop the start up message from popping up and enter the scratch +buffer instead. + +#+BEGIN_SRC emacs-lisp + (setq warning-minimum-level :emergency) + (setq inhibit-startup-message t + confirm-nonexistent-file-or-buffer nil + default-directory "~/") + (setq-default fill-column 80) + (setq-default truncate-lines t) + (tool-bar-mode 0) + (unless (string= system-type "darwin") + (menu-bar-mode 0)) + (fset 'yes-or-no-p 'y-or-n-p) + (global-hl-line-mode 1) + (add-to-list 'custom-theme-load-path "~/.emacs.d/themes/") + (add-to-list 'load-path "~/.emacs.d/modes/") + (setq ring-bell-function 'ignore) + (when (eq system-type 'darwin) + (setq dired-use-ls-dired nil)) +#+END_SRC + +#+BEGIN_SRC emacs-lisp + (global-unset-key (kbd "C-z")) + (when (eq system-type 'darwin) + (setq mac-right-option-modifier 'none + mac-option-key-is-meta nil + mac-command-key-is-meta t + mac-command-modifier 'meta + mac-option-modifier nil)) + + (global-set-key (kbd "M-u") #'upcase-dwim) + (global-set-key (kbd "M-l") #'downcase-dwim) + (global-set-key (kbd "M-c") #'capitalize-dwim) + (global-set-key (kbd "C-c z") #'quick-calc) + (global-set-key (kbd "") #'revert-buffer) + (global-set-key (kbd "C-c q") #'y/exit-emacs-client) + (global-set-key (kbd "C-c i") #'y/eshell-here) + (global-set-key (kbd "C-.") #'other-window) + (global-set-key (kbd "C-,") #'prev-window) + (global-set-key (kbd "C-`") #'push-mark-no-activate) + (global-set-key (kbd "M-`") #'jump-to-mark) + + (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) +#+END_SRC + +#+begin_src emacs-lisp + (global-visual-line-mode t) +#+end_src + +*** Custom modeline + +Editing the modeline. ~%c~ might be a bit slow though, so that could be removed +if that is ever a problem. + +#+BEGIN_SRC emacs-lisp + (defun -custom-modeline-github-vc () + (let ((branch (mapconcat 'concat (cdr (split-string vc-mode "[:-]")) "-"))) + (concat + (propertize (format " %s" (all-the-icons-octicon "git-branch")) + 'face `(:height 1 :family ,(all-the-icons-octicon-family)) + 'display '(raise 0)) + (propertize (format " %s" branch)) + (propertize " ")))) + + (defun -custom-modeline-svn-vc () + (let ((revision (cadr (split-string vc-mode "-")))) + (concat + (propertize (format " %s" (all-the-icons-faicon "cloud")) + 'face `(:height 1) + 'display '(raise 0)) + (propertize (format " %s" revision) 'face `(:height 0.9))))) + + (define-minor-mode minor-mode-blackout-mode + "Hides minor modes from the mode line." + t) + + (catch 'done + (mapc (lambda (x) + (when (and (consp x) + (equal (cadr x) '("" minor-mode-alist))) + (let ((original (copy-sequence x))) + (setcar x 'minor-mode-blackout-mode) + (setcdr x (list "" original))) + (throw 'done t))) + mode-line-modes)) + + (defun simple-mode-line-render (left middle right) + "Return a string of `window-width' length containing LEFT, and RIGHT aligned respectively." + (let* ((available-width + (/ (- (window-total-width) + (+ (length (format-mode-line left)) + (length (format-mode-line right)) + (length (format-mode-line middle)))) + 2))) + (append left (list (format (format "%%%ds" available-width) "")) + middle (list (format (format "%%%ds" available-width) "")) + right))) + + (setq-default mode-line-format + '((:eval + (simple-mode-line-render + (quote (" " mode-line-modified + " " mode-line-buffer-identification + " %l:%c " mode-line-modes " ")) + (quote ((:propertize + (:eval (when vc-mode + (cond + ((string-match "Git[:-]" vc-mode) (-custom-modeline-github-vc)) + ((string-match "SVN-" vc-mode) (-custom-modeline-svn-vc)) + (t (format "%s" vc-mode))))) + face mode-line-vc))) + (quote (" " mode-line-misc-info)))))) +#+END_SRC + +Move the backup files into the temporaty directory so that they are out of the +way. + +#+BEGIN_SRC emacs-lisp + (setq backup-directory-alist + `((".*" . ,temporary-file-directory))) + (setq auto-save-file-name-transforms + `((".*" ,temporary-file-directory t))) +#+END_SRC + +Make emacs follow symlinks every time, this means that it will open the actual +file and go to where the file is actually stored instead of editing it through +the symlink. This enables the use of git and other version control when editing +the file. +#+BEGIN_SRC emacs-lisp + (setq vc-follow-symlinks t) +#+END_SRC + +This stops paren mode with interfering with the modeline. +#+BEGIN_SRC emacs-lisp + (show-paren-mode 'expression) +#+END_SRC + +Revert the buffer automatically when a file changes on disc. This is useful when +monitoring a file such as a log file. It will also do this silently. +#+BEGIN_SRC emacs-lisp + (global-auto-revert-mode 1) + (setq auto-revert-verbose nil) +#+END_SRC + +Disable tabs, I want to move towards only using spaces everywhere as that is my +preferred style. This is just personal preference though. +#+BEGIN_SRC emacs-lisp + (setq-default indent-tabs-mode nil) + (setq-default tab-width 4) + (setq tab-width 4) + (setq-default python-indent-offset 4) + (setq-default c-basic-offset 4) + (setq-default python-indent 4) +#+END_SRC + +Set the line number display very high so that it is always shown in the modeline. +#+BEGIN_SRC emacs-lisp + (setq line-number-display-limit 2000000) +#+END_SRC + +Set the undo correctly +#+BEGIN_SRC emacs-lisp + (define-key global-map (kbd "C-\\") 'undo-only) +#+END_SRC + +Setting up my keybindings + +#+BEGIN_SRC emacs-lisp + (defun y/swap-windows () + "Swaps two windows and leaves the cursor in the original one" + (interactive) + (ace-swap-window) + (aw-flip-window)) + + (defun y/exit-emacs-client () + "consistent exit emacsclient. If not in emacs client, echo a + message in minibuffer, don't exit emacs. If in server mode and + editing file, do C-x # server-edit else do C-x 5 0 + delete-frame" + (interactive) + (if server-buffer-clients + (server-edit) + (delete-frame))) + + (defun y/beautify-json () + (interactive) + (let ((b (if mark-active (min (point) (mark)) (point-min))) + (e (if mark-active (max (point) (mark)) (point-max)))) + (shell-command-on-region b e + "python -m json.tool" (current-buffer) t))) + + (use-package pass + :commands (password-store-copy + password-store-insert + password-store-generate)) + + (define-prefix-command 'y-map) + (global-set-key (kbd "C-c y") 'y-map) + + (define-key y-map (kbd "s") 'y/swap-windows) + (define-key y-map (kbd "j") 'y/beautify-json) + (define-key y-map (kbd "p") 'password-store-copy) + (define-key y-map (kbd "i") 'password-store-insert) + (define-key y-map (kbd "g") 'password-store-generate) + (define-key y-map (kbd "r") 'toggle-rot13-mode) +#+END_SRC + +Set the font to Hack, which is an opensource monospace font designed for +programming and looking at source code. + +#+BEGIN_SRC text + (set-default-font "Misc Tamsyn-16") + (setq default-frame-alist '((font . "Misc Tamsyn-16"))) +#+END_SRC + +#+BEGIN_SRC emacs-lisp + (if (string= system-type "darwin") + (set-face-attribute 'default nil + :family "Iosevka" :height 145 :weight 'normal) + (progn + (set-default-font "Iosevka Medium-16") + (setq default-frame-alist '((font . "Iosevka Medium-16"))))) +#+END_SRC + +#+BEGIN_SRC emacs-lisp + (use-package eshell + :ensure nil + :bind (("C-c e" . eshell)) + :init + (defun eshell/vi (&rest args) + "Invoke `find-file' on the file. + \"vi +42 foo\" also goes to line 42 in the buffer." + (while args + (if (string-match "\\`\\+\\([0-9]+\\)\\'" (car args)) + (let* ((line (string-to-number (match-string 1 (pop args)))) + (file (pop args))) + (find-file file) + (goto-line line)) + (find-file (pop args))))) + + (defun eshell/em (&rest args) + "Open a file in emacs. Some habits die hard." + (if (null args) + (bury-buffer) + (mapc #'find-file (mapcar #'expand-file-name (eshell-flatten-list (reverse args)))))) + + (defun y/eshell-here () + "Go to eshell and set current directory to the buffer's directory" + (interactive) + (let ((dir (file-name-directory (or (buffer-file-name) + default-directory)))) + (eshell) + (eshell/pushd ".") + (cd dir) + (goto-char (point-max)) + (eshell-kill-input) + (eshell-send-input)))) +#+END_SRC + +*** Reload + +#+BEGIN_SRC emacs-lisp + (defun y/reload () + (interactive) + (load-file (expand-file-name "~/.emacs.d/init.el"))) +#+END_SRC + +* Social +** Mail +~mu4e~ is automatically in the load path when installed through a package +manager. + +For archlinux, the command to install mu4e is: + +#+BEGIN_SRC shell + pacman -S mu +#+END_SRC + +which comes with mu. + +Set the email client to be mu4e in emacs, and set the correct mail directory. As +I am downloading all the mailboxes, there will be duplicates, which can be +ignored in searches by setting ~mu4e-headers-skip-duplicates~. + +Also delete messages when they are sent, and don't copy them over to the sent +directory, as Gmail will do that for us. + +To download the mail using imap, I use ~mbsync~, which downloads all mail with +the ~-a~ flag. + +Finally, remove buffers when an email has been sent. + +#+BEGIN_SRC text + (load-user-file "personal.el") +#+END_SRC + +** Elfeed + +#+BEGIN_SRC emacs-lisp + (use-package elfeed-org + :config + (elfeed-org) + (setq rmh-elfeed-org-files + (list (expand-file-name "~/Annex/Dropbox/org/elfeed.org")))) + + (use-package elfeed + :bind (:map elfeed-search-mode-map + ("A" . y/elfeed-show-all) + ("E" . y/elfeed-show-emacs) + ("D" . y/elfeed-show-daily) + ("q" . y/elfeed-save-db-and-bury))) +#+END_SRC + +Define utility functions to make the reader work. + +#+BEGIN_SRC emacs-lisp + (defun y/elfeed-show-all () + (interactive) + (bookmark-maybe-load-default-file) + (bookmark-jump "elfeed-all")) + + (defun y/elfeed-show-emacs () + (interactive) + (bookmark-maybe-load-default-file) + (bookmark-jump "elfeed-emacs")) + + (defun y/elfeed-show-daily () + (interactive) + (bookmark-maybe-load-default-file) + (bookmark-jump "elfeed-daily")) + + ;;functions to support syncing .elfeed between machines + ;;makes sure elfeed reads index from disk before launching + (defun y/elfeed-load-db-and-open () + "Wrapper to load the elfeed db from disk before opening" + (interactive) + (elfeed-db-load) + (elfeed) + (elfeed-search-update--force)) + + ;;write to disk when quiting + (defun y/elfeed-save-db-and-bury () + "Wrapper to save the elfeed db to disk before burying buffer" + (interactive) + (elfeed-db-save) + (quit-window)) +#+END_SRC + +* Utility +** Zettelkasten + +#+begin_src emacs-lisp + (when (file-directory-p "~/projects/emacs-zettelkasten") + (add-to-list 'load-path "~/projects/emacs-zettelkasten") + (require 'zettelkasten) + (zettelkasten-mode t)) +#+end_src + +** Navigation + +Set navigation commands in all the buffers +#+BEGIN_SRC emacs-lisp + (defun prev-window () + (interactive) + (other-window -1)) + + (defun push-mark-no-activate () + "Pushes `point' to `mark-ring' and does not activate the region + Equivalent to \\[set-mark-command] when \\[transient-mark-mode] is disabled" + (interactive) + (push-mark (point) t nil) + (message "Pushed mark to ring")) + + (defun jump-to-mark () + "Jumps to the local mark, respecting the `mark-ring' order. + This is the same as using \\[set-mark-command] with the prefix argument." + (interactive) + (set-mark-command 1)) +#+END_SRC + +Enable winner mode to save window state. +#+BEGIN_SRC emacs-lisp + (winner-mode 1) +#+END_SRC + +#+BEGIN_SRC emacs-lisp + (use-package flx) + + (use-package ivy + :bind + (("C-c s" . swiper) + ("M-x" . counsel-M-x) + ("C-x C-f" . counsel-find-file) + ("C-c g" . counsel-git) + ("C-c j" . counsel-git-grep) + ("C-c C-r" . ivy-resume) + ("C-x b" . ivy-switch-buffer) + ("C-x 8 RET" . counsel-unicode-char)) + :config + (ivy-mode 1) + (counsel-mode t) + (setq ivy-use-virtual-buffers t) + (setq ivy-count-format "(%d/%d) ") + (define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history) + (setq ivy-re-builders-alist + '((t . ivy--regex-fuzzy)))) +#+END_SRC + +#+begin_src emacs-lisp + (use-package avy + :bind + (("C-'" . avy-goto-char-2)) + :config + (setq avy-keys '(?a ?r ?s ?t ?d ?h ?n ?e ?i ?o))) +#+end_src + +** Visual +*** All the icons +#+BEGIN_SRC emacs-lisp + (use-package all-the-icons) +#+END_SRC + +** Editing +*** Hungry Delete +#+BEGIN_SRC emacs-lisp + (use-package hungry-delete + :config + (global-hungry-delete-mode)) +#+END_SRC + +*** SmartParens +#+BEGIN_SRC emacs-lisp + (use-package smartparens + :bind (("M-[" . sp-backward-unwrap-sexp) + ("M-]" . sp-unwrap-sexp) + ("C-M-f" . sp-forward-sexp) + ("C-M-b" . sp-backward-sexp) + ("C-M-d" . sp-down-sexp) + ("C-M-a" . sp-backward-down-sexp) + ("C-M-e" . sp-up-sexp) + ("C-M-u" . sp-backward-up-sexp) + ("C-M-t" . sp-transpose-sexp) + ("C-M-n" . sp-next-sexp) + ("C-M-p" . sp-previous-sexp) + ("C-M-k" . sp-kill-sexp) + ("C-M-w" . sp-copy-sexp) + ("C-)" . sp-forward-slurp-sexp) + ("C-}" . sp-forward-barf-sexp) + ("C-(" . sp-backward-slurp-sexp) + ("C-{" . sp-backward-barf-sexp) + ("M-D" . sp-splice-sexp) + ("C-]" . sp-select-next-thing-exchange) + ("C-" . sp-select-previous-thing) + ("C-M-]" . sp-select-next-thing) + ("M-F" . sp-forward-symbol) + ("M-B" . sp-backward-symbol) + ("M-S" . sp-split-sexp)) + :hook ((minibuffer-setup) . turn-on-smartparens-strict-mode) + :config + (require 'smartparens-config) + (show-smartparens-global-mode +1) + (smartparens-global-mode 1) + + (sp-with-modes '(c-mode c++-mode) + (sp-local-pair "{" nil :post-handlers '(("||\n[i]" "RET"))) + (sp-local-pair "/*" "*/" :post-handlers '((" | " "SPC") + ("* ||\n[i]" "RET"))))) +#+END_SRC + +*** Whitespace +#+BEGIN_SRC emacs-lisp + (use-package whitespace + :bind (("C-x w" . whitespace-mode))) +#+END_SRC + +*** IEdit +#+BEGIN_SRC emacs-lisp + (use-package iedit + :bind (("C-;" . iedit-mode))) +#+END_SRC + +*** Expand Region + +Expand region is very useful to select words and structures quickly by +incrementally selecting more and more of the text. + +#+BEGIN_SRC emacs-lisp + (use-package expand-region + :bind ("M-o" . er/expand-region)) +#+END_SRC + +*** Dired + +#+BEGIN_SRC emacs-lisp + (add-hook 'dired-load-hook + (function (lambda () (load "dired-x")))) + + (setq dired-dwim-target t) +#+END_SRC + +** Search +*** Deadgrep + +#+BEGIN_SRC emacs-lisp + (use-package deadgrep + :bind (("C-c d" . deadgrep))) +#+END_SRC + +** Yasnippets + +#+BEGIN_SRC emacs-lisp + (use-package yasnippet + :config + (yas-global-mode)) +#+END_SRC + +** Nix + +#+BEGIN_SRC emacs-lisp + (use-package direnv + :config (direnv-mode)) +#+END_SRC + +* Writing + +** Spellcheck in emacs +#+BEGIN_SRC emacs-lisp + (use-package flyspell + :ensure nil + :hook + (text-mode . flyspell-mode) + :init + (setq ispell-dictionary "en_GB") + (setq ispell-dictionary-alist + '(("en_GB" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_GB") nil utf-8))) + (setq ispell-program-name (executable-find "hunspell")) + (setq ispell-really-hunspell t) + :config + (define-key flyspell-mode-map (kbd "C-.") nil) + (define-key flyspell-mode-map (kbd "C-,") nil)) +#+END_SRC + +** Latex +#+BEGIN_SRC emacs-lisp + (use-package tex-site + :ensure auctex + :mode (".tex'" . latex-mode) + :config + ;; to use pdfview with auctex + (setq TeX-view-program-selection '((output-pdf "PDF Tools")) + TeX-view-program-list '(("PDF Tools" TeX-pdf-tools-sync-view)) + TeX-source-correlate-start-server t) ;; not sure if last line is neccessary + ;; to have the buffer refresh after compilation + (add-hook 'TeX-after-compilation-finished-functions + #'TeX-revert-document-buffer) + (setq TeX-engine 'luatex) + (setq TeX-auto-save t) + (setq TeX-parse-self t) + (setq-default TeX-command-extra-options "-shell-escape") + (setq TeX-save-query nil) + (setq-default TeX-master nil) + (setq TeX-PDF-mode t) + (add-hook 'LaTeX-mode-hook 'flyspell-mode) + (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode) + (defun turn-on-outline-minor-mode () + (outline-minor-mode 1)) + (add-hook 'LaTeX-mode-hook 'turn-on-outline-minor-mode) + (setq outline-minor-mode-prefix "\C-c \C-o") + (autoload 'reftex-mode "reftex" "RefTeX Minor Mode" t) + (autoload 'turn-on-reftex "reftex" "RefTeX Minor Mode" nil) + (autoload 'reftex-citation "reftex-cite" "Make citation" nil) + (autoload 'reftex-index-phrase-mode "reftex-index" "Phrase Mode" t) + (add-hook 'LaTeX-mode-hook 'turn-on-reftex) + (setq reftex-bibliography-commands '("bibliography" "nobibliography" "addbibresource")) + (setq org-latex-listings 'minted) + (add-to-list 'org-latex-packages-alist '("" "minted")) ; with Emacs latex mode + + (require 'ox-latex)) +#+END_SRC + +** Markdown +Markdown is the standard for writing documentation. This snippet loads GFM +(Github Flavoured Markdown) style. + +#+BEGIN_SRC emacs-lisp + (use-package markdown-mode + :commands (markdown-mode gfm-mode) + :mode (("README\\.md\\'" . gfm-mode) + ("\\.md\\'" . markdown-mode) + ("\\.markdown\\'" . markdown-mode)) + :init (setq markdown-command "multimarkdown")) +#+END_SRC + +** Org + +#+BEGIN_SRC emacs-lisp + (use-package org + :ensure org-plus-contrib + :pin org + :config + (setq org-log-into-drawer t + org-log-done "note" + org-hide-leading-stars t + org-confirm-babel-evaluate nil + org-directory (expand-file-name "~/Dropbox/org") + org-image-actual-width nil + org-format-latex-options (plist-put org-format-latex-options :scale 1.5) + org-latex-pdf-process (list "latexmk -lualatex -shell-escape -bibtex -f -pdf %f") + org-default-notes-file (concat org-directory "/inbox.org") + org-image-actual-width nil + org-export-allow-bind-keywords t) + + (eval-after-load "org" + '(setq org-metaup-hook nil + org-metadown-hook nil)) + + (add-hook 'org-trigger-hook 'save-buffer)) +#+END_SRC + +Set up ob for executing code blocks + +#+BEGIN_SRC emacs-lisp + (use-package ob + :ensure nil + :config + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (js . t) + (java . t) + (haskell . t) + (python . t) + (ruby . t) + (org . t) + (matlab . t) + (ditaa . t) + (clojure . t) + (dot . t) + (shell . t)))) +#+END_SRC + +Exporting to html needs htmlize. + +#+BEGIN_SRC emacs-lisp + (use-package htmlize + :commands (htmlize-file + htmlize-buffer + htmlize-region + htmlize-many-files + htmlize-many-files-dired + htmlize-region-save-screenshot)) +#+END_SRC + +Add md backend + +#+BEGIN_SRC emacs-lisp + (require 'ox-md) +#+END_SRC + +Add org noter + +#+BEGIN_SRC emacs-lisp + (use-package org-noter + :after org + :config (setq org-noter-default-notes-file-names '("notes.org") + org-noter-notes-search-path '("~/org/bibliography") + org-noter-separate-notes-from-heading t)) + + (use-package org-ref + :after org + :bind (("C-c r" . org-ref-cite-hydra/body) + ("C-c b" . org-ref-bibtex-hydra/body)) + :init + (require 'org-ref) + :config + (setq org-ref-bibliography-notes "~/Dropbox/bibliography/notes.org" + org-ref-default-bibliography '("~/Dropbox/bibliography/references.bib") + org-ref-pdf-directory "~/Dropbox/bibliography/papers/") + (setq org-ref-completion-library 'org-ref-ivy-cite)) +#+END_SRC + +*** Org ID + +#+begin_src emacs-lisp + (use-package org-id + :ensure nil + :after org) +#+end_src + +*** Templates +#+BEGIN_SRC emacs-lisp + (setq org-capture-templates + '(("t" "todo" entry (file+headline "~/Dropbox/org/inbox.org" "Tasks") + "* TODO %?\n\n%i\n%a\n\n") + ())) +#+END_SRC + +*** Agenda + +#+BEGIN_SRC emacs-lisp + (setq org-agenda-files (mapcar 'expand-file-name + (list "~/Dropbox/org/inbox.org" + "~/Dropbox/org/main.org" + "~/Dropbox/org/tickler.org" + (format-time-string "~/Dropbox/org/journals/%Y-%m.org"))) + org-refile-targets `(("~/Dropbox/org/main.org" :maxlevel . 2) + ("~/Dropbox/org/someday.org" :level . 1) + ("~/Dropbox/org/tickler.org" :maxlevel . 2) + (,(format-time-string "~/Dropbox/org/journals/%Y-%m.org") :maxlevel . 2)) + org-todo-keywords '((sequence "TODO(t)" "WAITING(w)" "|" "DONE(d)" "CANCELLED(c)"))) + + (setq org-agenda-custom-commands + '(("w" "At work" tags-todo "@work" + ((org-agenda-overriding-header "Work"))) + ("h" "At home" tags-todo "@home" + ((org-agenda-overriding-header "Home"))) + ("u" "At uni" tags-todo "@uni" + ((org-agenda-overriding-header "University"))))) +#+END_SRC + +*** Contacts + +#+BEGIN_SRC emacs-lisp + (setq org-contacts-files (mapcar 'expand-file-name + '("~/Dropbox/org/contacts.org"))) +#+END_SRC + +*** Remove Binding +#+BEGIN_SRC emacs-lisp + (define-key org-mode-map (kbd "C-,") nil) +#+END_SRC + +*** Registers + +#+BEGIN_SRC emacs-lisp + (set-register ?l (cons 'file "~/.emacs.d/loader.org")) + (set-register ?m (cons 'file "~/Dropbox/org/main.org")) + (set-register ?i (cons 'file "~/Dropbox/org/inbox.org")) + (set-register ?c (cons 'file (format-time-string "~/Dropbox/org/journals/%Y-%m.org"))) +#+END_SRC + +*** Exporting + +#+BEGIN_SRC emacs-lisp + (use-package ox-twbs) +#+END_SRC + +** PDF Tools + +#+BEGIN_SRC emacs-lisp + (use-package pdf-tools + :config + ;; initialise + (pdf-tools-install) + ;; open pdfs scaled to fit page + (setq-default pdf-view-display-size 'fit-page) + ;; automatically annotate highlights + (setq pdf-annot-activate-created-annotations t) + ;; use normal isearch + (define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)) +#+END_SRC + +** Writeroom + +#+begin_src emacs-lisp + (use-package writeroom-mode + :config + (setq writeroom-width 100)) +#+end_src + +* Programming +My emacs configuration is mostly focused on programming, therefore there is a +lot of different language support. + +** Version Control and Project Management +*** Magit +#+BEGIN_SRC emacs-lisp + (use-package magit + :bind (("C-x g" . magit-status)) + :config + (setq server-switch-hook nil)) +#+END_SRC + +*** Projectile +#+BEGIN_SRC emacs-lisp + (use-package projectile + :config + (projectile-mode +1) + (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map) + (setq projectile-enable-caching nil) + (setq projectile-git-submodule-command "") + (setq projectile-mode-line '(:eval (format " Proj[%s]" (projectile-project-name)))) + (defun projectile-tags-exclude-patterns () "")) + + (use-package counsel-projectile + :config + (counsel-projectile-mode t)) +#+END_SRC + +*** Diff + +#+BEGIN_SRC emacs-lisp + (defun command-line-diff (switch) + (let ((file1 (pop command-line-args-left)) + (file2 (pop command-line-args-left))) + (ediff file1 file2))) + (add-to-list 'command-switch-alist '("diff" . command-line-diff)) + (setq-default ediff-forward-word-function 'forward-char) +#+END_SRC + +** Language Support +*** C++ + +Setting up CC mode with a hook that uses my settings. + +#+BEGIN_SRC emacs-lisp + (use-package cc-mode + :config + (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) + (setq c-default-style "linux" + tab-width 4 + c-indent-level 4) + (defun my-c++-mode-hook () + (c-set-offset 'inline-open 0) + (c-set-offset 'inline-close 0) + (c-set-offset 'innamespace 0) + (c-set-offset 'arglist-cont-nonempty 8) + (setq indent-tabs-mode nil)) + (add-hook 'c-mode-hook 'my-c++-mode-hook) + (add-hook 'c++-mode-hook 'my-c++-mode-hook) + + (define-key c-mode-map (kbd "C-c C-c") 'comment-or-uncomment-region)) +#+END_SRC + +Adding C headers to company backend for completion. + +#+BEGIN_SRC emacs-lisp + (use-package irony + :config + (add-hook 'c++-mode-hook 'irony-mode) + (add-hook 'c-mode-hook 'irony-mode) + (add-hook 'objc-mode-hook 'irony-mode) + + (defun my-irony-mode-hook () + (define-key irony-mode-map [remap completion-at-point] + 'irony-completion-at-point-async) + (define-key irony-mode-map [remap complete-symbol] + 'irony-completion-at-point-async)) + (add-hook 'irony-mode-hook 'my-irony-mode-hook) + (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)) + + (use-package company-irony) + + (use-package flycheck-irony + :config + (add-hook 'c++-mode-hook #'flycheck-irony-setup)) + + (use-package company-c-headers + :config + (add-to-list 'company-backends 'company-c-headers) + (add-to-list 'company-backends 'company-irony) + + (add-hook 'irony-mode-hook 'company-irony-setup-begin-commands)) +#+END_SRC + +Using clang format to format the region that is currently being selected (need +to install clang format script). + +#+BEGIN_SRC emacs-lisp + (use-package clang-format + :bind (("C-c C-i" . 'clang-format-region) + ("C-c u" . 'clang-format-buffer))) +#+END_SRC + +*** Clojure +Using Cider for clojure environment. + +#+BEGIN_SRC emacs-lisp + (use-package cider + :commands cider-mode + :config + (setq cider-repl-display-help-banner nil)) +#+END_SRC + +Adding hook to clojure mode to enable strict parentheses mode. + +#+BEGIN_SRC emacs-lisp + (add-hook 'clojure-mode-hook 'turn-on-smartparens-strict-mode) +#+END_SRC + +*** CMake +#+BEGIN_SRC emacs-lisp + (use-package cmake-mode + :commands cmake-mode + :config + (setq auto-mode-alist + (append + '(("CMakeLists\\.txt\\'" . cmake-mode)) + '(("\\.cmake\\'" . cmake-mode)) + auto-mode-alist)) + (autoload 'cmake-mode "~/CMake/Auxiliary/cmake-mode.el" t)) +#+END_SRC + +*** Coq + +#+begin_src emacs-lisp + (use-package proof-general + :config + (setq coq-compile-before-require t) + (setq proof-splash-enable nil)) +#+end_src + +*** Elm + +#+BEGIN_SRC emacs-lisp + (use-package elm-mode + :mode ("\\.elm\\'")) +#+END_SRC + +*** Emacs Lisp +Adding strict parentheses to emacs lisp. + +#+BEGIN_SRC emacs-lisp + (add-hook 'emacs-lisp-mode-hook 'turn-on-smartparens-strict-mode) +#+END_SRC + +*** F# +F# mode for uni work. + +#+BEGIN_SRC emacs-lisp + (use-package fsharp-mode + :commands fsharp-mode + :config + (defun y/fsharp-reload-file () + "Reloads the whole file when in fsharp mode." + (interactive) + (fsharp-eval-region (point-min) (point-max))) + (add-hook 'fsharp-mode-hook + (lambda () (local-set-key (kbd "C-c C-c") #'y/fsharp-reload-file)))) +#+END_SRC + +*** Flex + +#+begin_src emacs-lisp + (add-to-list 'auto-mode-alist '("\\.flex\\'" . c-mode)) +#+end_src + +*** Haskell + +Haskell mode with company mode completion. + +#+BEGIN_SRC emacs-lisp + (defun y/haskell-align-comment (start end) + (interactive "r") + (align-regexp start end "\\(\\s-*\\)--")) + + (use-package haskell-mode + :commands haskell-mode + :bind (("M-." . haskell-mode-jump-to-def)) + :config + (add-hook 'haskell-mode-hook 'haskell-decl-scan-mode) + (add-hook 'haskell-mode-hook (lambda () + (local-set-key (kbd "C-c y a") 'y/haskell-align-comment))) + (add-hook 'haskell-mode-hook (lambda () + (local-set-key (kbd "C-c v") 'haskell-add-import))) + (add-hook 'haskell-mode-hook (lambda () + (set (make-local-variable 'projectile-tags-command) + "hasktags -Re -f \"%s\" %s \"%s\""))) + (setq ;;haskell-mode-stylish-haskell-path "brittany" + flycheck-ghc-language-extensions '("OverloadedStrings")) + + (setq haskell-indentation-layout-offset 4 + haskell-indentation-starter-offset 4 + haskell-indentation-left-offset 4 + haskell-indentation-where-pre-offset 2 + haskell-indentation-where-post-offset 2)) + + + (use-package interactive-haskell-mode + :ensure haskell-mode + :hook haskell-mode) +#+END_SRC + +*** LLVM IR + +#+begin_src emacs-lisp + (when (file-exists-p "~/.emacs.d/modes/llvm-mode.el") + (require 'llvm-mode)) +#+end_src + +*** HOL + +#+begin_src emacs-lisp + (when (file-exists-p "/opt/hol/tools/hol-mode.el") + (setq hol-executable "/opt/hol/bin/hol") + (load "/opt/hol/tools/hol-mode.el")) +#+end_src + +*** Python +Elpy package for python, which provides an IDE type environment for python. + +#+BEGIN_SRC emacs-lisp + (use-package elpy + :commands python-mode + :config + (elpy-enable) + (setq py-python-command "python3") + (setq python-shell-interpreter "python3")) + (setq tab-width 4) + + (with-eval-after-load 'python + (defun python-shell-completion-native-try () + "Return non-nil if can trigger native completion." + (let ((python-shell-completion-native-enable t) + (python-shell-completion-native-output-timeout + python-shell-completion-native-try-output-timeout)) + (python-shell-completion-native-get-completions + (get-buffer-process (current-buffer)) + nil "_")))) +#+END_SRC + +*** JSON +JSON files should be opened in js-mode. +#+BEGIN_SRC emacs-lisp + (add-to-list 'auto-mode-alist '("\\.json\\'" . js-mode)) +#+END_SRC + +*** SCSS +#+BEGIN_SRC emacs-lisp + (use-package css-mode + :ensure nil + :commands (scss-mode + css-mode) + :config + (setq css-indent-offset 2)) +#+END_SRC + +*** Scala + +#+begin_src emacs-lisp + (use-package scala-mode) +#+end_src + +*** Shell +#+BEGIN_SRC emacs-lisp + (setq sh-basic-offset 2) + (setq sh-indentation 2) +#+END_SRC + +*** SMTLIBv2 + +#+begin_src emacs-lisp + (require 'smtlib-mode) + (add-to-list 'auto-mode-alist '("\\.smt\\'" . smtlib-mode)) +#+end_src + +*** Verilog + +#+begin_src emacs-lisp + (setq flycheck-verilog-verilator-executable "verilator_bin") +#+end_src + +** Completion Support +*** Company +#+BEGIN_SRC emacs-lisp + (use-package company + :config + (add-hook 'after-init-hook 'global-company-mode) + (setq company-backends (delete 'company-semantic company-backends)) + + (define-key c-mode-map (kbd "C-c n") 'company-complete) + (define-key c++-mode-map (kbd "C-c n") 'company-complete) + (setq company-dabbrev-downcase 0)) +#+END_SRC + +*** Flycheck +Enabling global flycheck support. +#+BEGIN_SRC emacs-lisp + (use-package flycheck + :config (global-flycheck-mode)) +#+END_SRC + +*** Yasnippets +#+BEGIN_SRC emacs-lisp + (use-package yasnippet + :hook ((org-mode cc-mode) . yas-minor-mode) + :config + (yas-minor-mode 1)) +#+END_SRC + +*** SMerge + +Shamelessly taken from https://github.com/alphapapa/unpackaged.el#hydra. +#+BEGIN_SRC emacs-lisp + (use-package smerge-mode + :config + (defhydra unpackaged/smerge-hydra + (:color pink :hint nil :post (smerge-auto-leave)) + " + ^Move^ ^Keep^ ^Diff^ ^Other^ + ^^-----------^^-------------------^^---------------------^^------- + _n_ext _b_ase _<_: upper/base _C_ombine + _p_rev _u_pper _=_: upper/lower _r_esolve + ^^ _l_ower _>_: base/lower _k_ill current + ^^ _a_ll _R_efine + ^^ _RET_: current _E_diff + " + ("n" smerge-next) + ("p" smerge-prev) + ("b" smerge-keep-base) + ("u" smerge-keep-upper) + ("l" smerge-keep-lower) + ("a" smerge-keep-all) + ("RET" smerge-keep-current) + ("\C-m" smerge-keep-current) + ("<" smerge-diff-base-upper) + ("=" smerge-diff-upper-lower) + (">" smerge-diff-base-lower) + ("R" smerge-refine) + ("E" smerge-ediff) + ("C" smerge-combine-with-next) + ("r" smerge-resolve) + ("k" smerge-kill-current) + ("ZZ" (lambda () + (interactive) + (save-buffer) + (bury-buffer)) + "Save and bury buffer" :color blue) + ("q" nil "cancel" :color blue)) + :hook (magit-diff-visit-file . (lambda () + (when smerge-mode + (unpackaged/smerge-hydra/body))))) +#+END_SRC + +* Look and Feel + +#+BEGIN_SRC emacs-lisp + (defadvice load-theme + (before theme-dont-propagate activate) + (mapc #'disable-theme custom-enabled-themes)) + + (add-hook 'after-make-frame-functions + (lambda (frame) + (select-frame frame) + (toggle-scroll-bar -1))) + + (unless (boundp 'server-process) + (progn (load-theme 'sanityinc-tomorrow-night t) + (toggle-scroll-bar -1))) +#+END_SRC + +* Conclusion +Setting the gc-cons threshold back to what it was at the beginning. + +#+BEGIN_SRC emacs-lisp + (server-start) + (setq gc-cons-threshold (* 1024 1024 10)) +#+END_SRC -- cgit