Skip to content

Instantly share code, notes, and snippets.

@juev
Forked from nilsdeppe/emacs.el
Created Apr 2, 2018
Embed
What would you like to do?
My Emacs init file
;;; initfile --- Summary:
;;; Commentary:
;; Emacs 25.1 and newer tested
;;; Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Configuration/Customization:
;; Defines global variables that are later used to customize and set
;; up packages.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Specify the ycmd server command and path to the ycmd directory *inside* the
;; cloned ycmd directory
(defvar my:ycmd-server-command '("python" "/home/nils/Research/ycmd/ycmd"))
(defvar my:ycmd-extra-conf-whitelist '("~/.ycm_extra_conf.py"))
(defvar my:ycmd-global-config "~/.ycm_extra_conf.py")
;; Specify the jupyter executable name, and the start dir of the server
(defvar my:jupyter_location (executable-find "jupyter"))
(defvar my:jupyter_start_dir "/home/nils")
;; Compilation command for C/C++
(defvar my:compile-command "clang++ -Wall -Wextra -std=c++14 ")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; By default Emacs triggers garbage collection at ~0.8MB which makes
;; startup really slow. Since most systems have at least 64MB of memory,
;; we increase it during initialization.
(setq gc-cons-threshold 64000000)
(add-hook 'after-init-hook #'(lambda ()
;; restore after startup
(setq gc-cons-threshold 800000)))
;; Extra plugins and config files are stored here
(add-to-list 'load-path (expand-file-name "~/.emacs.d/plugins"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Start emacs server if not already running
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (and (fboundp 'server-running-p)
(not (server-running-p)))
(server-start))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; General Tweaks
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; turn on highlight matching brackets when cursor is on one
(show-paren-mode t)
;; Overwrite region selected
(delete-selection-mode t)
;; Show column numbers by default
(setq column-number-mode t)
;; Use CUA to delete selections
(setq cua-mode t)
(setq cua-enable-cua-keys nil)
;; Prevent emacs from creating a bckup file filename~
(setq make-backup-files nil)
;; Settings for searching
(setq-default case-fold-search t ;case insensitive searches by default
search-highlight t) ;hilit matches when searching
;; Highlight the line we are currently on
(global-hl-line-mode t)
;; Disable the toolbar at the top since it's useless
(if (functionp 'tool-bar-mode) (tool-bar-mode -1))
;; Remove trailing white space upon saving
;; Note: because of a bug in EIN we only delete trailing whitespace
;; when not in EIN mode.
(add-hook 'before-save-hook
(lambda ()
(when (not (derived-mode-p 'ein:notebook-multilang-mode))
(delete-trailing-whitespace))))
;; Auto-wrap at 80 characters
(setq-default auto-fill-function 'do-auto-fill)
(setq-default fill-column 80)
(turn-on-auto-fill)
;; Disable auto-fill-mode in programming mode
(add-hook 'prog-mode-hook (lambda () (auto-fill-mode -1)))
;; Global Keyboard Shortcuts
;; Set help to C-?
(global-set-key (kbd "C-?") 'help-command)
;; Set mark paragraph to M-?
(global-set-key (kbd "M-?") 'mark-paragraph)
;; Set backspace to C-h
(global-set-key (kbd "C-h") 'delete-backward-char)
;; Set backspace word to M-h
(global-set-key (kbd "M-h") 'backward-kill-word)
;; Use meta+tab word completion
(global-set-key (kbd "M-TAB") 'dabbrev-expand)
;; Easy undo key
(global-set-key (kbd "C-/") 'undo)
;; Comment or uncomment the region
(global-set-key (kbd "C-c ;") 'comment-or-uncomment-region)
;; Indent after a newline, if required by syntax of language
(global-set-key (kbd "C-m") 'newline-and-indent)
;; Load the compile ocmmand
(global-set-key (kbd "C-c C-c") 'compile)
;; Undo, basically C-x u
(global-set-key (kbd "C-/") 'undo)
;; Find file in project
(global-set-key (kbd "C-x M-f") 'project-find-file)
;; We don't want to type yes and no all the time so, do y and n
(defalias 'yes-or-no-p 'y-or-n-p)
;; Disable the horrid auto-save
(setq auto-save-default nil)
;; Disable the menu bar since we don't use it, especially not in the
;; terminal
(when (and (not (eq system-type 'darwin)) (fboundp 'menu-bar-mode))
(menu-bar-mode -1))
;; Don't ring the bell
(setq ring-bell-function 'ignore)
;; Non-nil means draw block cursor as wide as the glyph under it.
;; For example, if a block cursor is over a tab, it will be drawn as
;; wide as that tab on the display.
(setq x-stretch-cursor t)
;; Dont ask to follow symlink in git
(setq vc-follow-symlinks t)
;; Check (on save) whether the file edited contains a shebang, if yes,
;; make it executable from
;; http://mbork.pl/2015-01-10_A_few_random_Emacs_tips
(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
;; Highlight some keywords in prog-mode
(add-hook 'prog-mode-hook
(lambda ()
(font-lock-add-keywords
nil
'(("\\<\\(FIXME\\|TODO\\|BUG\\|DONE\\)" 1 font-lock-warning-face t)
)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set packages to install
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq package-archives '(("melpa" . "http://melpa.milkbox.net/packages/")
("gnu" . "http://elpa.gnu.org/packages/")))
;; Disable package initialize after us. We either initialize it
;; anyway in case of interpreted .emacs, or we don't want slow
;; initizlization in case of byte-compiled .emacs.elc.
(setq package-enable-at-startup nil)
;; Ask package.el to not add (package-initialize) to .emacs.
(setq package--init-file-ensured t)
;; set use-package-verbose to t for interpreted .emacs,
;; and to nil for byte-compiled .emacs.elc
(eval-and-compile
(setq use-package-verbose (not (bound-and-true-p byte-compile-current-file))))
;; Add the macro generated list of package.el loadpaths to load-path.
(mapc #'(lambda (add) (add-to-list 'load-path add))
(eval-when-compile
(require 'package)
(package-initialize)
;; Install use-package if not installed yet.
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
;; (require 'use-package)
(let ((package-user-dir-real (file-truename package-user-dir)))
;; The reverse is necessary, because outside we mapc
;; add-to-list element-by-element, which reverses.
(nreverse (apply #'nconc
;; Only keep package.el provided loadpaths.
(mapcar #'(lambda (path)
(if (string-prefix-p package-user-dir-real path)
(list path)
nil))
load-path))))))
(eval-when-compile
(require 'use-package))
(use-package bind-key)
;; so we can (require 'use-package) even in compiled emacs to e.g. read docs
(use-package use-package
:commands use-package-autoload-keymap)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Enable terminal emacs to copy and paste from system clipboard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Note: this uses C-c before the usual C-w, M-w, and C-y
;; From: https://stackoverflow.com/questions/64360/how-to-copy-text-from-emacs-to-another-application-on-linux
(defun my-copy-to-xclipboard(arg)
(interactive "P")
(cond
((not (use-region-p))
(message "Nothing to yank to X-clipboard"))
((and (not (display-graphic-p))
(/= 0 (shell-command-on-region
(region-beginning) (region-end) "xsel -i -b")))
(message "Error: Is program `xsel' installed?"))
(t
(when (display-graphic-p)
(call-interactively 'clipboard-kill-ring-save))
(message "Yanked region to X-clipboard")
(when arg
(kill-region (region-beginning) (region-end)))
(deactivate-mark))))
(defun my-cut-to-xclipboard()
(interactive)
(my-copy-to-xclipboard t))
(defun my-paste-from-xclipboard()
(interactive)
(if (display-graphic-p)
(clipboard-yank)
(insert (shell-command-to-string "xsel -o -b"))))
(global-set-key (kbd "C-c C-w") 'my-cut-to-xclipboard)
(global-set-key (kbd "C-c M-w") 'my-copy-to-xclipboard)
(global-set-key (kbd "C-c C-y") 'my-paste-from-xclipboard)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; async - library for async/thread processing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package async
:ensure t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Automatically compile and save ~/.emacs.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun byte-compile-init-files (file)
"Automatically compile FILE."
(interactive)
(save-restriction
;; Suppress the warning when you setq an undefined variable.
(if (>= emacs-major-version 23)
(setq byte-compile-warnings '(not free-vars obsolete))
(setq byte-compile-warnings
'(unresolved
callargs
redefine
obsolete
noruntime
cl-warnings
interactive-only)))
(byte-compile-file (expand-file-name file)))
)
(add-hook
'after-save-hook
(function
(lambda ()
(if (string= (file-truename "~/.emacs.el")
(file-truename (buffer-file-name)))
(byte-compile-init-files (file-truename "~/.emacs.el")))
)
)
)
;; Byte-compile again to ~/.emacs.elc if it is outdated
(if (file-newer-than-file-p
(file-truename "~/.emacs.el")
(file-truename "~/.emacs.elc"))
(byte-compile-init-files "~/.emacs.el"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Ivy config
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package ivy
:ensure t
:config
(require 'ivy)
(ivy-mode t)
(setq ivy-use-virtual-buffers t)
(setq enable-recursive-minibuffers t)
(setq ivy-wrap t)
(global-set-key (kbd "C-c C-r") 'ivy-resume)
;; Show #/total when scrolling buffers
(setq ivy-count-format "%d/%d ")
)
(use-package swiper
:ensure t
:bind (("C-s" . swiper)
("C-r" . swiper))
)
(use-package counsel
:ensure t
:bind (("M-x" . counsel-M-x)
("C-x C-f" . counsel-find-file)
("<f1> f" . counsel-describe-function)
("<f1> v" . counsel-describe-variable)
("<f1> l" . counsel-find-library)
("<f2> i" . counsel-info-lookup-symbol)
("<f2> u" . counsel-unicode-char)
("C-c g" . counsel-git-grep)
("C-c j" . counsel-git)
("C-c k" . counsel-ag)
("C-c r" . counsel-rg)
("C-x l" . counsel-locate)
:map minibuffer-local-map
("C-r" . counsel-minibuffer-add)
)
:config
(if (executable-find "rg")
;; use ripgrep instead of grep because it's way faster
(setq counsel-grep-base-command
"rg -i -M 120 --no-heading --line-number --color never '%s' %s"
counsel-rg-base-command
"rg -i -M 120 --no-heading --line-number --color never %s ."
)
(warn "\nWARNING: Could not find the ripgrep executable. It "
"is recommended you install ripgrep.")
)
)
;; Use universal ctags to build the tags database for the project.
;; When you first want to build a TAGS database run 'touch TAGS'
;; in the root directory of your project.
(use-package counsel-etags
:ensure t
:bind (
("M-." . counsel-etags-find-tag-at-point)
("M-t" . counsel-etags-grep-symbol-at-point)
("M-s" . counsel-etags-find-tag))
:config
;; Ignore files above 800kb
(setq counsel-etags-max-file-size 800)
;; Ignore build directories for tagging
(add-to-list 'counsel-etags-ignore-directories '"build*")
(add-to-list 'counsel-etags-ignore-directories '".vscode")
(add-to-list 'counsel-etags-ignore-filenames '".clang-format")
;; Don't ask before rereading the TAGS files if they have changed
(setq tags-revert-without-query t)
;; Don't warn when TAGS files are large
(setq large-file-warning-threshold nil)
;; How many seconds to wait before rerunning tags for auto-update
(setq counsel-etags-update-interval 180)
;; Set up auto-update
(add-hook
'prog-mode-hook
(lambda () (add-hook 'after-save-hook
(lambda ()
(counsel-etags-virtual-update-tags))))
)
;; The function provided by counsel-etags is broken (at least on Linux)
;; and doesn't correctly exclude directories, leading to an excessive
;; amount of incorrect tags. The issue seems to be that the trailing '/'
;; in e.g. '*dirname/*' causes 'find' to not correctly exclude all files
;; in that directory, only files in sub-directories of the dir set to be
;; ignore.
(defun my-scan-dir (src-dir &optional force)
"Create tags file from SRC-DIR. \
If FORCE is t, the commmand is executed without \
checking the timer."
(let* ((find-pg (or
counsel-etags-find-program
(counsel-etags-guess-program "find")))
(ctags-pg (or
counsel-etags-tags-program
(format "%s -e -L" (counsel-etags-guess-program
"ctags"))))
(default-directory src-dir)
;; run find&ctags to create TAGS
(cmd (format
"%s . \\( %s \\) -prune -o -type f -not -size +%sk %s | %s -"
find-pg
(mapconcat
(lambda (p)
(format "-iwholename \"*%s*\"" p))
counsel-etags-ignore-directories " -or ")
counsel-etags-max-file-size
(mapconcat (lambda (n)
(format "-not -name \"%s\"" n))
counsel-etags-ignore-filenames " ")
ctags-pg))
(tags-file (concat (file-name-as-directory src-dir) "TAGS"))
(doit (or force (not (file-exists-p tags-file)))))
;; always update cli options
(when doit
(message "%s at %s" cmd default-directory)
(shell-command cmd)
(visit-tags-table tags-file t)
)
)
)
(setq counsel-etags-update-tags-backend
(lambda ()
(interactive)
(let* ((tags-file (counsel-etags-locate-tags-file)))
(when tags-file
(my-scan-dir (file-name-directory tags-file) t)
(run-hook-with-args
'counsel-etags-after-update-tags-hook tags-file)
(unless counsel-etags-quiet-when-updating-tags
(message "%s is updated!" tags-file))))
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Window numbering
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Package window-numbering installed from package list
;; Allows switching between buffers using meta-(# key)
(use-package window-numbering
:ensure t
:config
(window-numbering-mode t)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; wgrep
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; wgrep allows you to edit all files in a grep result. For example,
;; you can use C-c g or C-c r to search all files in a project, then
;; use C-c C-o to enter ivy-occur mode, followed by 'w' to make
;; the grep results buffer editable, then you can edit the results
;; however you wish.
(use-package wgrep
:ensure t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Python mode settings
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq-default python-indent 4)
(setq-default python-indent-offset 4)
(add-hook 'python-mode-hook
(lambda ()
(setq tab-width 4)))
(use-package elpy
:ensure t
:after python
:config
(elpy-enable)
)
(use-package yapfify
:ensure t
:init
(add-hook 'python-mode-hook 'yapf-mode))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Clang-format
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; clang-format can be triggered using C-c C-f
;; Create clang-format file using google style
;; clang-format -style=google -dump-config > .clang-format
(use-package clang-format
:ensure t
:bind (("C-c C-f" . clang-format-region))
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Modern C++ code highlighting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package modern-cpp-font-lock
:ensure t
:config
(modern-c++-font-lock-global-mode t)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; C++ keys
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package cc-mode
:ensure t
:config
(define-key c++-mode-map (kbd "C-c C-c") 'compile)
(define-key c++-mode-map (kbd "C-c C-k") 'kill-compilation)
(setq compile-command my:compile-command)
(use-package google-c-style
:ensure t
:config
;; This prevents the extra two spaces in a namespace that Emacs
;; otherwise wants to put... Gawd!
(add-hook 'c-mode-common-hook 'google-set-c-style)
;; Autoindent using google style guide
(add-hook 'c-mode-common-hook 'google-make-newline-indent)
)
)
;; Change tab key behavior to insert spaces instead
(setq-default indent-tabs-mode nil)
;; Set the number of spaces that the tab key inserts (usually 2 or 4)
(setq c-basic-offset 2)
;; Set the size that a tab CHARACTER is interpreted as
;; (unnecessary if there are no tab characters in the file!)
(setq tab-width 2)
;; We want to be able to see if there is a tab character vs a space.
;; global-whitespace-mode allows us to do just that.
;; Set whitespace mode to only show tabs, not newlines/spaces.
(use-package whitespace
:ensure t
:config
(setq whitespace-style '(tabs tab-mark))
;; Turn on whitespace mode globally.
(global-whitespace-mode t)
)
;; Enable hide/show of code blocks
(add-hook 'c-mode-common-hook 'hs-minor-mode)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Package: ycmd (YouCompleteMeDaemon)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set up YouCompleteMe for emacs:
;; https://github.com/Valloric/ycmd
;; https://github.com/abingham/emacs-ycmd
(defvar my:python-location (executable-find (nth 0 my:ycmd-server-command)))
(if (not my:python-location)
(message
"Could not start YouCompleteMeDaemon because the python executable could
not be found.\nSpecified executable is: '%s'\nPlease set my:ycmd-server-command
appropriately in ~/.emacs.el.\n" (nth 0 my:ycmd-server-command)))
(if (not (file-directory-p (nth 1 my:ycmd-server-command)))
(message "Could not YouCompleteMeDaemon because the specified directory does
not exist.\nSpecified directory is: '%s'\nPlease set my:ycmd-server-command
appropriately in ~/.emacs.el.\n" (nth 1 my:ycmd-server-command)))
(if (and my:python-location
(file-directory-p (nth 1 my:ycmd-server-command)))
(use-package ycmd
:ensure t
:init
(add-hook 'after-init-hook #'global-ycmd-mode)
:config
(progn
(set-variable 'ycmd-server-command my:ycmd-server-command)
(set-variable 'ycmd-extra-conf-whitelist my:ycmd-extra-conf-whitelist)
(set-variable 'ycmd-global-config my:ycmd-global-config)
(setq ycmd-force-semantic-completion t)
(use-package company-ycmd
:ensure t
:config
(company-ycmd-setup)
)
(use-package flycheck-ycmd
:ensure t
:init
(add-hook 'c-mode-common-hook 'flycheck-ycmd-setup)
)
;; Add displaying the function arguments in mini buffer using El Doc
(use-package ycmd-eldoc
:init
;; For some reason ycmd-eldoc doesn't work properly in Python mode.
;; I get a "connection refused" error when it connects to JediHTTP
(add-hook 'c-mode-common-hook
(lambda ()
(ycmd-eldoc-mode t)))
)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set up code completion with company
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package company
:ensure t
:config
;; Zero delay when pressing tab
(setq company-idle-delay 0)
(add-hook 'after-init-hook 'global-company-mode)
;; remove unused backends
(setq company-backends (delete 'company-semantic company-backends))
(setq company-backends (delete 'company-eclim company-backends))
(setq company-backends (delete 'company-xcode company-backends))
(setq company-backends (delete 'company-clang company-backends))
(setq company-backends (delete 'company-bbdb company-backends))
(setq company-backends (delete 'company-oddmuse company-backends))
)
;; Setup loading company-jedi for python completion
;; This requines running jedi:install-server the first time
(use-package company-jedi
:ensure t
:after python
:init
(defun my/python-mode-hook ()
(add-to-list 'company-backends 'company-jedi))
(add-hook 'python-mode-hook 'my/python-mode-hook)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Configure flycheck
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Note: For C++ we use flycheck-ycmd
(use-package flycheck
:ensure t
:defer t
:config
;; Turn flycheck on everywhere
(global-flycheck-mode t)
;; There are issues with company mode and flycheck in terminal mode.
;; This is outlined at:
;; https://github.com/abingham/emacs-ycmd
(when (not (display-graphic-p))
(setq flycheck-indication-mode nil))
)
(use-package flycheck-pyflakes
:ensure t
:after python)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Org-Mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq org-log-done 'time
org-todo-keywords '((sequence "TODO" "INPROGRESS" "DONE"))
org-todo-keyword-faces '(("INPROGRESS" . (:foreground "blue" :weight bold))))
(add-hook 'org-mode-hook
(lambda ()
(flyspell-mode)))
(use-package writegood-mode
:ensure t
:init
(add-hook 'org-mode-hook
(lambda () (writegood-mode))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; vlf - handle open very large files
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package vlf
:ensure t
:config
(require 'vlf-setup))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; web-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package web-mode
:ensure t
:mode (("\\.phtml\\'" . web-mode)
("\\.tpl\\.php\\'" . web-mode)
("\\.[agj]sp\\'" . web-mode)
("\\.as[cp]x\\'" . web-mode)
("\\.erb\\'" . web-mode)
("\\.mustache\\'" . web-mode)
("\\.djhtml\\'" . web-mode)
("\\.html?\\'" . web-mode))
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ein - ipython notebooks in gui emacs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Only launch if the executable exists.
(if (and my:jupyter_location
my:jupyter_start_dir)
(use-package ein
:ensure t
:defer 5
:config
(progn
;; We need to load additional packages for ein to work correctly when in
;; byte-compiled mode. The reason for this is that we do not use
;; package.el to initialize packages and so the EIN dependencies are
;; not properly configured. We first search for the directory
;; ".*/ein-.*" in the load-path. Once we found this entry we list all
;; el files in the directory, remove the extension, and then load the
;; ones that are required. The non-required ones are:
;; ein - can't depend on ourselves
;; debug-ein - we are not debugging
;; ein-pkg - we don't have package.el loaded, so RIP
(dolist (my:current-path load-path)
(if (string-match-p "/ein-" my:current-path)
(dolist (name (directory-files my:current-path nil
"\\.el$"))
(if (and (not (equal "ein" (file-name-sans-extension name)))
(not (equal "debug-ein"
(file-name-sans-extension name)))
(not (equal "ein-pkg"
(file-name-sans-extension name)))
)
(load (file-name-sans-extension name) nil t)
)
)
)
)
(ein:jupyter-server-start my:jupyter_location my:jupyter_start_dir)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; autopair
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Automatically at closing brace, bracket and quote
(use-package autopair
:ensure t
:config
(autopair-global-mode t)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load hungry Delete, caus we're lazy
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set hungry delete:
(use-package hungry-delete
:ensure t
:config
(global-hungry-delete-mode t)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Syntax Highlighting in CUDA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load CUDA mode so we get syntax highlighting in .cu files
(use-package cuda-mode
:ensure t
:mode (("\\.cu\\'" . cuda-mode)
("\\.cuh\\'" . cuda-mode)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Flyspell Mode for Spelling Corrections
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package flyspell
:ensure t
:init
(setq flyspell-issue-welcome-flag nil)
:config
(defun flyspell-check-next-highlighted-word ()
"Custom function to spell check next highlighted word."
(interactive)
(flyspell-goto-next-error)
(ispell-word))
(global-set-key (kbd "<f7>") 'flyspell-buffer)
(global-set-key (kbd "<f8>") 'flyspell-correct-previous)
(global-set-key (kbd "<f9>") 'flyspell-correct-previous)
(add-hook 'text-mode-hook #'flyspell-mode)
(add-hook 'prog-mode-hook #'flyspell-prog-mode)
)
(use-package flyspell-correct-ivy
:ensure t
:after flyspell)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Magit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package magit
:ensure t
:requires dash
:after (ivy)
:bind (("M-g M-s" . magit-status)
("M-g M-c" . 'magit-checkout)
)
:config
(add-hook 'magit-mode-hook (lambda () (setq whitespace-mode -1)))
(setq magit-completing-read-function 'ivy-completing-read)
)
(use-package magit-gerrit
:ensure t
:after magit
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GitGutter
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package git-gutter
:ensure t
:config
;; If you enable global minor mode
(global-git-gutter-mode t)
;; Auto update every 5 seconds
(custom-set-variables
'(git-gutter:update-interval 5))
;; Set the foreground color of modified lines to something obvious
(set-face-foreground 'git-gutter:modified "purple")
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; cmake-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package cmake-mode
:ensure t
:mode ("CMakeLists.txt" ".cmake"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; yaml-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package yaml-mode
:ensure t
:mode (".yml" ".yaml"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; json-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package json-mode
:ensure t
:mode (".json"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Setup Dockerfile mode
;; 1. Download file from GitHub
;; 2. Load mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (not (file-directory-p "~/.emacs.d/plugins"))
(make-directory "~/.emacs.d/plugins"))
(if (not (file-exists-p "~/.emacs.d/plugins/dockerfile-mode.el"))
(url-copy-file
"https://raw.githubusercontent.com/spotify/dockerfile-mode/master/dockerfile-mode.el"
"~/.emacs.d/plugins/dockerfile-mode.el"))
(use-package dockerfile-mode
:mode ("Dockerfile"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Package: yasnippet
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package yasnippet
:ensure t
:functions yas-global-mode yas-expand
:defer 5
:config
(yas-global-mode t)
(yas-reload-all))
(use-package yasnippet-snippets
:ensure t
:after yasnippet
:config
(yas-reload-all))
;; Apparently the company-yasnippet backend shadows all backends that
;; come after it. To work around this we assign yasnippet to a different
;; keybind since actual source completion is vital.
(use-package company-yasnippet
:bind ("C-M-y" . company-yasnippet)
:after (yasnippet)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load asm-mode when opening assembly files
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package asm-mode
:mode ("\\.s\\'"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Use markdown-mode for markdown files
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package markdown-mode
:ensure t
:mode (".md" ".markdown"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; auctex
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package tex-site
:ensure auctex
:mode ("\\.tex\\'" . latex-mode)
;; When we byte-compile we need to have the autoloads loaded in order to
;; properly get auctex working, otherwise auctex is not loaded correctly
:init
(load "auctex-autoloads" nil t)
:config
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq TeX-view-program-list
'(("Evince" "evince --page-index=%(outpage) %o")))
(setq TeX-view-program-selection '((output-pdf "Evince")))
(setq TeX-source-correlate-start-server t)
(add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)
(add-hook 'LaTeX-mode-hook 'auto-fill-mode)
(add-hook 'LaTeX-mode-hook 'flyspell-mode)
(add-hook 'LaTeX-mode-hook 'flyspell-buffer)
(add-hook 'LaTeX-mode-hook 'turn-on-reftex)
(setq reftex-plug-into-AUCTeX t)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Appearance
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The deeper blue theme is loaded but the resulting text
;; appears black in Aquamacs. This can be fixed by setting
;; the font color under Menu Bar->Options->Appearance->Font For...
;; and then setting "Adopt Face and Frame Parameter as Frame Default"
(use-package sourcerer-theme
:ensure t
:config
(load-theme 'sourcerer t))
(set-face-background 'hl-line "#372E2D")
;; The minibuffer default colors with my theme are impossible to read, so change
;; them to something better using ivy-minibuffer-match-face.
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(default ((((type tty) (background dark)) (:background "nil"))))
'(company-preview ((t (:background "#073642" :foreground "#2aa198"))))
'(company-preview-common ((t (:foreground "#93a1a1" :underline t))))
'(company-scrollbar-bg ((t (:background "#073642" :foreground "#2aa198"))))
'(company-scrollbar-fg ((t (:foreground "#002b36" :background "#839496"))))
'(company-template-field ((t (:background "#7B6000" :foreground "#073642"))))
'(company-tooltip ((t (:background "black" :foreground "DeepSkyBlue1"))))
'(company-tooltip-annotation ((t (:foreground "#93a1a1" :background "#073642"))))
'(company-tooltip-common ((t (:foreground "#93a1a1" :underline t))))
'(company-tooltip-common-selection ((t (:foreground "#93a1a1" :underline t))))
'(company-tooltip-mouse ((t (:background "DodgerBlue4" :foreground "CadetBlue1"))))
'(company-tooltip-selection ((t (:background "DodgerBlue4" :foreground "CadetBlue1"))))
'(header-line ((t (:background "#003366"))))
'(ivy-minibuffer-match-face-1 ((((class color) (background light)) (:background "#555555")) (((class color) (background dark)) (:background "#555555"))))
'(ivy-minibuffer-match-face-2 ((t (:background "#314f30" :weight bold))))
'(ivy-minibuffer-match-face-3 ((t (:background "#48225b" :weight bold))))
'(ivy-minibuffer-match-face-4 ((t (:background "#680a0a" :weight bold))))
'(which-func ((t (:foreground "#8fb28f")))))
;; I don't care to see the splash screen
(setq inhibit-splash-screen t)
;; Hide the scroll bar
(scroll-bar-mode -1)
(defvar my-font-size 90)
;; Make mode bar small
(set-face-attribute 'mode-line nil :height my-font-size)
;; Set the header bar font
(set-face-attribute 'header-line nil :height my-font-size)
;; Set default window size and position
(setq default-frame-alist
'((top . 0) (left . 0) ;; position
(width . 110) (height . 90) ;; size
))
;; Enable line numbers on the LHS
(global-linum-mode -1)
;; Set the font to size 9 (90/10).
(set-face-attribute 'default nil :height my-font-size)
(setq-default indicate-empty-lines t)
(when (not indicate-empty-lines)
(toggle-indicate-empty-lines))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Enable which function mode and set the header line to display both the
;; path and the function we're in
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(which-function-mode t)
;; Remove function from mode bar
(setq mode-line-misc-info
(delete (assoc 'which-func-mode
mode-line-misc-info) mode-line-misc-info))
(defmacro with-face
(str &rest properties)
`(propertize ,str 'face (list ,@properties)))
(defun sl/make-header ()
"."
(let* ((sl/full-header (abbreviate-file-name buffer-file-name))
(sl/header (file-name-directory sl/full-header))
(sl/drop-str "[...]")
)
(if (> (length sl/full-header)
(window-body-width))
(if (> (length sl/header)
(window-body-width))
(progn
(concat (with-face sl/drop-str
:background "blue"
:weight 'bold
)
(with-face (substring sl/header
(+ (- (length sl/header)
(window-body-width))
(length sl/drop-str))
(length sl/header))
;; :background "red"
:weight 'bold
)))
(concat
(with-face sl/header
;; :background "red"
:foreground "red"
:weight 'bold)))
(concat (if window-system ;; In the terminal the green is hard to read
(with-face sl/header
;; :background "green"
;; :foreground "black"
:weight 'bold
:foreground "#8fb28f"
)
(with-face sl/header
;; :background "green"
;; :foreground "black"
:weight 'bold
:foreground "blue"
))
(with-face (file-name-nondirectory buffer-file-name)
:weight 'bold
;; :background "red"
)))))
(defun sl/display-header ()
"Create the header string and display it."
;; The dark blue in the header for which-func is terrible to read.
;; However, in the terminal it's quite nice
(if window-system
(custom-set-faces
'(which-func ((t (:foreground "#8fb28f")))))
(custom-set-faces
'(which-func ((t (:foreground "blue"))))))
;; Set the header line
(setq header-line-format
(list "-"
'(which-func-mode ("" which-func-format))
'("" ;; invocation-name
(:eval (if (buffer-file-name)
(concat "[" (sl/make-header) "]")
"[%b]")))
)
)
)
;; Call the header line update
(add-hook 'buffer-list-update-hook
'sl/display-header)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Powerline theme
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; powerline theme where the modes are on the right side.
(use-package powerline
:ensure t
:config
(defun powerline-right-theme ()
"Setup a mode-line with major and minor modes on the right side."
(interactive)
(setq-default mode-line-format
'("%e"
(:eval
(let* ((active (powerline-selected-window-active))
(mode-line-buffer-id (if active 'mode-line-buffer-id 'mode-line-buffer-id-inactive))
(mode-line (if active 'mode-line 'mode-line-inactive))
(face0 (if active 'powerline-active0 'powerline-inactive0))
(face1 (if active 'powerline-active1 'powerline-inactive1))
(face2 (if active 'powerline-active2 'powerline-inactive2))
(separator-left (intern (format "powerline-%s-%s"
(powerline-current-separator)
(car powerline-default-separator-dir))))
(separator-right (intern (format "powerline-%s-%s"
(powerline-current-separator)
(cdr powerline-default-separator-dir))))
(lhs (list (powerline-raw "%*" face0 'l)
(powerline-buffer-size face0 'l)
(powerline-buffer-id `(mode-line-buffer-id ,face0) 'l)
(powerline-raw " ")
(funcall separator-left face0 face1)
(powerline-narrow face1 'l)
(powerline-vc face1)))
(center (list (powerline-raw global-mode-string face1 'r)
(powerline-raw "%4l" face1 'r)
(powerline-raw ":" face1)
(powerline-raw "%3c" face1 'r)
(funcall separator-right face1 face0)
(powerline-raw " ")
(powerline-raw "%6p" face0 'r)
(powerline-hud face2 face1)
))
(rhs (list (powerline-raw " " face1)
(funcall separator-left face1 face2)
(when (and (boundp 'erc-track-minor-mode) erc-track-minor-mode)
(powerline-raw erc-modified-channels-object face2 'l))
(powerline-major-mode face2 'l)
(powerline-process face2)
(powerline-raw " :" face2)
(powerline-minor-modes face2 'l)
(powerline-raw " " face2)
(funcall separator-right face2 face1)
))
)
(concat (powerline-render lhs)
(powerline-fill-center face1 (/ (powerline-width center) 2.0))
(powerline-render center)
(powerline-fill face1 (powerline-width rhs))
(powerline-render rhs)))))))
(powerline-right-theme)
)
(provide '.emacs)
;;; .emacs ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment