Skip to content

Instantly share code, notes, and snippets.

@nilsdeppe
Last active June 7, 2020 16:31
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save nilsdeppe/7645c096d93b005458d97d6874a91ea9 to your computer and use it in GitHub Desktop.
Save nilsdeppe/7645c096d93b005458d97d6874a91ea9 to your computer and use it in GitHub Desktop.
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 ")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set packages to install
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq package-archives '(("melpa-stable" . "https://stable.melpa.org/packages/")
("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))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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 ()
;; Highlighting in cmake-mode this way interferes with
;; cmake-font-lock, which is something I don't yet understand.
(when (not (derived-mode-p 'cmake-mode))
(font-lock-add-keywords
nil
'(("\\<\\(FIXME\\|TODO\\|BUG\\|DONE\\)"
1 font-lock-warning-face t))))
)
)
;; Setup use-package
(eval-when-compile
(require 'use-package))
(use-package bind-key
:ensure t)
;; 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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; s is used by ycmd, origami, etc and sometimes during Emacs
;; upgrades disappears so we try to install it on its own.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package s
: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"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; auto-package-update
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auto update packages once a week
(use-package auto-package-update
:ensure t
:commands (auto-package-update-maybe)
:config
(setq auto-package-update-delete-old-versions t)
(setq auto-package-update-hide-results t)
(auto-package-update-maybe)
(add-hook 'auto-package-update-before-hook
(lambda () (message "I will update packages now")))
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Ivy config
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package ivy
:ensure t
:commands (ivy-mode)
: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
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function counsel-etags-virtual-update-tags "counsel-etags.el")
(declare-function counsel-etags-guess-program "counsel-etags.el")
(declare-function counsel-etags-locate-tags-file "counsel-etags.el"))
: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
(eval-when-compile
;; Silence missing function warnings
(declare-function window-numbering-mode "window-numbering.el"))
(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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Edit server to allow editing of things in Chrome with Emacs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package edit-server
:ensure t
:config
(progn
(eval-when-compile
;; Silence missing function warnings
(declare-function edit-server-start "edit-server-start.el"))
(when (daemonp)
(edit-server-start)
)
(add-hook 'edit-server-start-hook
(lambda ()
(when (string-match "github.com" (buffer-name))
(markdown-mode))))
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Origami - Does code folding, ie hide the body of an
;; if/else/for/function so that you can fit more code on your screen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package origami
:ensure t
:commands (origami-mode)
:bind (:map origami-mode-map
("C-c o :" . origami-recursively-toggle-node)
("C-c o a" . origami-toggle-all-nodes)
("C-c o t" . origami-toggle-node)
("C-c o o" . origami-show-only-node)
("C-c o u" . origami-undo)
("C-c o U" . origami-redo)
("C-c o C-r" . origami-reset)
)
:config
(setq origami-show-fold-header t)
;; The python parser currently doesn't fold if/for/etc. blocks, which is
;; something we want. However, the basic indentation parser does support
;; this with one caveat: you must toggle the node when your cursor is on
;; the line of the if/for/etc. statement you want to collapse. You cannot
;; fold the statement by toggling in the body of the if/for/etc.
(add-to-list 'origami-parser-alist '(python-mode . origami-indent-parser))
:init
(add-hook 'prog-mode-hook 'origami-mode)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Rainbow Delimiters - have delimiters be colored by their depth
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package rainbow-delimiters
:ensure t
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function rainbow-delimiters-mode "rainbow-delimiters.el"))
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Beacon-mode: flash the cursor when switching buffers or scrolling
;; the goal is to make it easy to find the cursor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package beacon
:ensure t
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function beacon-mode "beacon.el"))
:config
(beacon-mode t))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; which-key: when you pause on a keyboard shortcut it provides
;; suggestions in a popup buffer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package which-key
:ensure t
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function which-key-mode "which-key.el"))
:config
(which-key-mode))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; avy: always fast jump to char inside the current view buffer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package avy
:ensure t
:bind (("M-c" . avy-goto-char)
("M-s" . avy-goto-word-1))
;; Set keys for Dvorak mode instead of qwerty
:init (setq avy-keys '(?a ?o ?e ?u ?i ?d ?h ?t ?n ?s
?A ?O ?E ?U ?I ?D ?H ?T ?N ?S
?p ?y ?f ?g ?c ?r ?l
?P ?Y ?F ?G ?C ?R ?L)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; zzz-to-char: replaces the built-in zap-to-char with avy-like
;; replacement options
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package zzz-to-char
:ensure t
:bind ("M-z" . zzz-up-to-char))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; RealGud - https://github.com/realgud/realgud
;; A rewrite of GUD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package realgud
:ensure t
:init
(setenv "TERM" "dumb")
:config
(setq realgud:pdb-command-name "python -m pdb"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Python mode settings
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq-default python-indent 4)
(setq-default python-indent-offset 4)
(add-hook 'python-mode-hook
(lambda ()
(setq tab-width 4)))
(setq-default pdb-command-name "python -m pdb")
(use-package elpy
:ensure t
:commands (elpy-enable)
: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
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function modern-c++-font-lock-global-mode
"modern-cpp-font-lock.el"))
:config
(modern-c++-font-lock-global-mode t)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; C++ keys
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package cc-mode
:ensure t
:init
(add-to-list 'auto-mode-alist '("\\.tpp\\'" . c++-mode))
: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
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function global-whitespace-mode "whitespace.el"))
: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'
Please 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
(eval-when-compile
;; Silence missing function warnings
(declare-function global-ycmd-mode "ycmd.el"))
(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
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function company-ycmd-setup "company-ycmd.el"))
: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
(require 'ycmd-eldoc)
(add-hook 'ycmd-mode-hook 'ycmd-eldoc-setup)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function global-flycheck-mode "flycheck.el"))
: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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; string-inflection
;; used for switching between different cases, eg CamelCase,
;; lowerCamelCase, snake_case, and SCREAMING_SNAKE_CASE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package string-inflection
:ensure t
:defer t
:bind (("C-c c i" . string-inflection-cycle)
("C-c c l" . string-inflection-lower-camelcase)
("C-c c c" . string-inflection-camelcase)
("C-c c s" . string-inflection-underscore)
("C-c c u" . string-inflection-upcase)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; multiple-cursors - https://github.com/magnars/multiple-cursors.el
;; Allows you to have multiple cursors on different lines so you can
;; easily edit multiple lines at once.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package multiple-cursors
:ensure t
:bind (("M-n" . mc/mark-next-like-this)
("M-p" . mc/mark-previous-like-this)
("C-c a" . mc/mark-all-like-this)
("C-c e" . mc/edit-lines))
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Org-Mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq org-log-done 'time
org-todo-keywords '((sequence "TODO" "INPROGRESS" "DONE"))
org-todo-keyword-faces '(("INPROGRESS" . (:foreground "blue" :weight bold))))
(use-package writegood-mode
:ensure t
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function writegood-mode "writegood-mode.el"))
(add-hook 'org-mode-hook #'writegood-mode)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; vlf - handle open very large files
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package vlf
:ensure t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
:commands (ein:jupyter-server-start)
:defer 5
:config
(require 'ein)
(require 'ein-loaddefs)
(require 'ein-notebook)
(require 'ein-subpackages)
;; when editing the emacs.el file, we do not want to start a new
;; Jupyter server each time we save, so we only start a new Jupyter
;; server if there currently isn't one running.
(defvar my-found-ein-server nil)
(dolist (my-current-process (process-list))
(when (string-match "EIN: Jupyter*" (process-name my-current-process))
(setq my-found-ein-server t))
)
(when (not my-found-ein-server)
(ein:jupyter-server-start my:jupyter_location my:jupyter_start_dir))
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; autopair
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Automatically at closing brace, bracket and quote
(use-package autopair
:ensure t
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function autopair-global-mode "autopair.el"))
:config
(autopair-global-mode t)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load hungry Delete, caus we're lazy
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Set hungry delete:
(use-package hungry-delete
:ensure t
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function global-hungry-delete-mode "hungry-delete.el"))
: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
(eval-when-compile
;; Silence missing function warnings
(declare-function flyspell-goto-next-error "flyspell.el")
(declare-function flyspell-mode "flyspell.el")
(declare-function flyspell-prog-mode "flyspell.el"))
(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)
(add-hook 'org-mode-hook #'flyspell-mode)
)
(use-package flyspell-correct-ivy
:ensure t
:after flyspell)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Magit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package magit
:ensure t
:requires dash
:after (ivy)
:commands (magit-checkout)
: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
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function global-git-gutter-mode "git-gutter.el"))
: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")
:hook (cmake-mode . (lambda ()
(add-to-list 'company-backends 'company-cmake)))
:config
(use-package cmake-font-lock
:ensure t
:defer t
:commands (cmake-font-lock-activate)
:hook (cmake-mode . (lambda ()
(cmake-font-lock-activate)
(font-lock-add-keywords
nil '(("\\<\\(FIXME\\|TODO\\|BUG\\|DONE\\)"
1 font-lock-warning-face t)))
))
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Bazel-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (not (file-exists-p "~/.emacs.d/plugins/bazel-mode.el"))
(url-copy-file
"https://raw.githubusercontent.com/codesuki/bazel-mode/master/bazel-mode.el"
"~/.emacs.d/plugins/bazel-mode.el"))
(if (file-exists-p "~/.emacs.d/plugins/bazel-mode.el")
(use-package bazel-mode
:mode ("BUILD" "\\.bazel\\'" "\\.bzl'" "WORKSPACE\\'")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; protobuf-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (not (file-exists-p "~/.emacs.d/plugins/protobuf-mode.el"))
(url-copy-file
"https://raw.githubusercontent.com/google/protobuf/master/editors/protobuf-mode.el"
"~/.emacs.d/plugins/protobuf-mode.el"))
(if (file-exists-p "~/.emacs.d/plugins/protobuf-mode.el")
(use-package protobuf-mode
:mode ("\\.proto")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; yaml-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package yaml-mode
:ensure t
:mode (".yml" ".yaml"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; json-mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package json-mode
:ensure t
:mode (".json" ".imp"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
:commands (yas-reload-all)
:init
(eval-when-compile
;; Silence missing function warnings
(declare-function yas-global-mode "yasnippet.el"))
: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-default TeX-auto-save t
TeX-parse-self t
TeX-source-correlate-start-server t)
(cond
((string-equal system-type "windows-nt") ; Microsoft Windows
(progn
(message "Windows does not have a PDF viewer set for auctex")))
((string-equal system-type "darwin") ; Mac OS X
(setq-default
TeX-view-program-list
'(("Skim"
"/Applications/Skim.app/Contents/SharedSupport/displayline -b -g %n %o %b")
)
TeX-view-program-selection '((output-pdf "Skim"))))
((string-equal system-type "gnu/linux") ; linux
(setq-default TeX-view-program-list
'(("Evince" "evince --page-index=%(outpage) %o"))
TeX-view-program-selection '((output-pdf "Evince")))))
(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-default 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
@nilsdeppe
Copy link
Author

Just did an overhaul to reduce startup time. This uses use-package and a few other tricks. Also added support for editing Jupyter notebooks in GUI emacs. I don't do a lot with python or Jupyter notebooks, but when I do use the notebooks I don't want to be stuck in a web browser without code completion and keyboard shortcuts.

@nilsdeppe
Copy link
Author

  • Switched from py-yapf to yapfify because py-yapf loses the kill ring when it runs and this was driving me crazy
  • Remove scroll bar, etc. even in -nw mode so that they are not present when connecting a GUI emacs-client to a daemon
  • Move configuration variables to front of file so it is much easier to configure the file.
  • Better checks for executables installed on the system so that ycmd, jupyter, and ripgrep are only used if actually installed. This helps portability of the file, which I've now successfully installed on several supercomputers.

@nilsdeppe
Copy link
Author

  • Updated auctex configuration, adding sync support with Evince and fixing a bug with the package support libs not being loaded correctly from the byte-compiled file.

@nilsdeppe
Copy link
Author

I have made several improvements to the .emacs.el file. In no particular order:

  • Fix the various incorrect warnings when compiling the file
  • Add IWYU .imp files to json mode
  • Add .tpp files to C++ mode
  • Add cmake-font-lock to get better highlighting of CMake files
  • Clean up EIN setup removing manually loading of packages and now check if a server is running before starting a new one
  • Add multiple-cursors package to allow editing multiple lines at once
  • Use string-inflection package to toggle between CamelCase, lowerCamelCase, snake_case, and SCREAMING_SNAKE_CASE
  • Improve ycmd-eldoc functionality
  • Add RealGUD for replacing the provided GUD.
  • Add origami-mode for code folding
  • Use edit-server to allow connecting to Emacs from, e.g. Chrome
  • Setup auto-updating of Emacs packages
  • Move Set packages to installsections closer to front of file

@nilsdeppe
Copy link
Author

  • Added support for viewing LaTeX pdfs with Skim on macOS and Evince on Linux (Emacs OS detection is used to switch automatically)

@nilsdeppe
Copy link
Author

Added:

  • Rainbow delimiters to make keeping track of which paren/brace/brackets go together easier
  • beacon-mode to flash the cursor when scrolling so it's easier to find
  • which-key to help you remember what key combination does what when you're in the middle of one
  • avy to quickly move around the current viewing area of the buffer (the keyboard shortcuts are currently set to be easy to use for Dvorak users, I'll add an option at the beginning of the file in the future)
  • zzz-to-char to replace zap-to-char for quickly deleting parts of the viewing area

@dandennison84
Copy link

Where can I find project-find-file? What package is it defined in?

@lazywithclass
Copy link

lazywithclass commented Jun 11, 2018

Thank you so much for this (and for the blog post) @nilsdeppe Helped me quite a lot getting up to speed with my Emacs conf.

@meysamkia
Copy link

So helpful. Thanks

@nilsdeppe
Copy link
Author

I'm moving towards sharing more of my environment (zshrc will be next) so I've set up a repo: https://github.com/nilsdeppe/MyEnvironment

I will update the code there instead. Thank you everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment