This is a collection of dotfiles and scripts for my bspwm setup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

21 KiB

Ricemacs, an Emacs Configuration

Initial setup

These commands need to be run after the first startup.

Irony mode

M-x irony-install-server

All the icons

M-x all-the-icons-install-fonts

Customizations

Store custom-file separately, don't freak out when it's not found.

  (setq custom-file "~/.emacs.d/custom.el")
  (load custom-file 'noerror)

Set custom faces, without using customize.

  (set-face-attribute 'default nil :height 90 :family "DejaVu Sans Mono")

Package Management

Ensure

Ensures packages are installed by default.

  (require 'use-package-ensure)
  (setq use-package-always-ensure t)

Auto update

Update pending updates of installed packages at startup. https://github.com/rranelli/auto-package-update.el

  (use-package auto-package-update
	:custom
	(auto-package-update-delete-old-versions t)
	(auto-package-update-hide-results t)
	:config
	(auto-package-update-maybe))

Compile

Automatically compile all packages. https://github.com/emacscollective/auto-compile

  (use-package auto-compile
	:custom (load-prefer-newer t)
	:config
	(auto-compile-on-load-mode)
	(auto-compile-on-save-mode))

Packages

Install and configure packages.

General

  (use-package color-theme-sanityinc-tomorrow
	:config
	(load-theme 'sanityinc-tomorrow-night t)
	(color-theme-sanityinc-tomorrow--with-colors 'night
	  (custom-theme-set-faces
		'sanityinc-tomorrow-night
		`(highlight                ((t (:foreground ,yellow :background ,background))))
		`(lazy-highlight           ((t (:foreground ,highlight :background ,comment))))
		`(line-number-current-line ((t (:foreground ,yellow :background "#222427"))))
		`(show-paren-match         ((t (:background ,yellow))))
		`(cursor                   ((t (:background ,foreground))))
		`(font-lock-keyword-face   ((t (:foreground ,green))))
		`(font-lock-string-face    ((t (:foreground ,aqua))))
		`(ivy-current-match        ((t (:foreground ,orange))))
		`(ivy-cursor               ((t (:background ,foreground))))
		)))

  (use-package which-key
	:config (which-key-mode))

  (use-package general
	:after which-key)

  (use-package ido-vertical-mode
	:config (ido-vertical-mode))

  (use-package smex
	:defer t
	:custom (smex-prompt-string "Command: ")
	:config (smex-initialize))

  (use-package avy
	:defer t)

  (use-package hungry-delete
	:config (global-hungry-delete-mode))

  (use-package smart-tabs-mode
	:config
	(smart-tabs-add-language-support latex latex-mode-hook
	  ((latex-indent-line . 4)
	   (latex-indent-region . 4)))
	(smart-tabs-insinuate 'c 'c++ 'java 'python 'latex))

Evil

Evil mode and related packages.

  (use-package undo-tree)
  (use-package goto-chg)

  (use-package evil
 :after (undo-tree goto-chg)
 :custom
 (evil-search-module 'evil-search)
 (evil-ex-complete-emacs-commands nil)
 (evil-vsplit-window-right t)
 (evil-split-window-below t)
 (evil-shift-round nil)
 (evil-want-C-u-scroll t)
 ;; Do not set half cursor in operator mode
 (evil-operator-state-cursor '(box))
 ;; Needed by evil-collection
 (evil-want-integration t)
 (evil-want-keybinding nil)
 :config (evil-mode))

  (use-package evil-collection
 :after evil
 :custom
 (evil-collection-company-use-tng nil)
 (evil-collection-key-blacklist '("M-h" "M-l"))
 (evil-collection-setup-minibuffer t)
 :config (evil-collection-init))

  (use-package evil-nerd-commenter
 :after evil)

Telephone Line

Emacs mode line replacement.

  (use-package telephone-line
	:custom-face
	(telephone-line-evil ((t (:weight normal))))
	(telephone-line-evil-normal ((t (:background "#87afd7" :foreground "black"))))
	(telephone-line-evil-insert ((t (:background "#b5bd68" :foreground "black"))))
	(telephone-line-evil-visual ((t (:background "#b294bb" :foreground "black"))))
	(telephone-line-evil-replace ((t (:background "#282a2e" :foreground "white"))))
	(telephone-line-evil-motion ((t (:background "#8abeb7" :foreground "black"))))
	(telephone-line-evil-operator ((t (:background "#de935f" :foreground "black"))))
	(telephone-line-evil-emacs ((t (:background "#b294bb" :foreground "black"))))
	:config (telephone-line-mode))

NeoTree

Collect icon fonts and propertize them within Emacs
(requires M-x all-the-icons-install-fonts).

  (use-package memoize)
  (use-package all-the-icons
	:after memoize)

Provides Emacs with a file tree.

  (use-package neotree
	:defer t
	:custom (neo-theme (if (display-graphic-p) 'icons 'arrow))
	:hook (neotree-mode . (lambda (&rest _) (display-line-numbers-mode 0)))
	:init
	(evil-set-initial-state 'neotree-mode 'normal)
	(evil-define-key 'normal neotree-mode-map
	  (kbd "RET")       'neotree-enter
	  (kbd "<backtab>") 'neotree-collapse-all ; <S-tab>
	  (kbd "c")         'neotree-create-node
	  (kbd "r")         'neotree-rename-node
	  (kbd "d")         'neotree-delete-node
	  (kbd "h")         'neotree-select-previous-sibling-node
	  (kbd "j")         'neotree-next-line
	  (kbd "k")         'neotree-previous-line
	  (kbd "l")         'neotree-enter
	  (kbd "R")         'neotree-refresh
	  (kbd "C")         'neotree-change-root
	  (kbd "I")         'neotree-hidden-file-toggle
	  (kbd "H")         'neotree-hidden-file-toggle
	  (kbd "q")         'neotree-hide))

Centaur Tabs

Places buffers as tabs in a bar at the top.

  (use-package centaur-tabs
	:custom
	(centaur-tabs-background-color "#282a2e")
	(centaur-tabs-height 40)
	(centaur-tabs-style "slant")
	(centaur-tabs-set-icons t)
	;; (centaur-tabs-set-modified-marker t)
	;; (centaur-tabs-modified-marker "*")
	;; (centaur-tabs-height 29)
	;; (centaur-tabs-set-icons nil)
	:custom-face
	(centaur-tabs-default ((t (:background "#282a2e" :foreground "#282a2e"))))
	(centaur-tabs-selected ((t (:background "#373b41" :foreground "white"))))
	(centaur-tabs-unselected ((t (:background "#282a2e" :foreground "#c5c8c6"))))
	:config
	(centaur-tabs-mode))

Completion

Autocomplete packages (includes code completion and snippets).

  (use-package company
	:defer t
	:custom
	(company-idle-delay 0.2)
	(company-minimum-prefix-length 2)
	:init
	(add-hook 'c-mode-common-hook 'company-mode)
	(add-hook 'emacs-lisp-mode-hook 'company-mode)
	(add-hook 'latex-mode-hook 'company-mode)
	(add-hook 'org-mode-hook 'company-mode)
	(add-hook 'shell-mode-hook 'company-mode)
	(add-hook 'shell-script-mode-hook 'company-mode))

  (use-package company-irony
	:after company
	:config (add-to-list 'company-backends 'company-irony))

  (use-package company-c-headers
	:after company
	:config (add-to-list 'company-backends 'company-c-headers))

Irony requires M-x irony-install-server.

(use-package irony
	:defer t
	:init
	(add-hook 'c++-mode-hook 'irony-mode)
	(add-hook 'c-mode-hook 'irony-mode)
	(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
	:config (push 'glsl-mode irony-supported-major-modes))

  (use-package yasnippet
	:defer t
	:init
	(add-hook 'org-mode-hook #'yas-minor-mode)
	(add-hook 'prog-mode-hook #'yas-minor-mode)
	:config (yas-reload-all))

  (use-package yasnippet-snippets
	:after yasnippet)

Prettify

  (use-package rainbow-mode
	:defer t
	:init (add-hook 'prog-mode-hook 'rainbow-mode))

  (use-package rainbow-delimiters
	:defer t
	:init (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))

  (use-package org-bullets
	:defer t
	:init (add-hook 'org-mode-hook 'org-bullets-mode))

  ;; Shader syntax highlighting
  (use-package glsl-mode
	:defer t)

  ;; Mark code after the 80 column range
  (use-package column-enforce-mode
	:defer t
	:custom (column-enforce-comments nil)
	:custom-face (column-enforce-face ((t (:background "#373b41" :foreground "#de935f"))))
	:init (add-hook 'prog-mode-hook 'column-enforce-mode))

Possible modern replacement for column-enforce-mode: https://github.com/laishulu/hl-fill-column

General

  ;; Scrolling
  (setq scroll-conservatively 1)
  (setq mouse-wheel-scroll-amount '(5))
  (setq mouse-wheel-progressive-speed nil)

  ;; Columns start at 1
  (setq column-number-indicator-zero-based nil)

  ;; Automatically add newline on save at the end of the file
  (setq require-final-newline t)

  ;; Enable line numbers
  (global-display-line-numbers-mode)

  ;; C++ syntax highlighting for .h files
  (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

  ;; When in the GUI version of Emacs, enable pretty symbols
  (when window-system (global-prettify-symbols-mode t))

Buffers

  ;; Buffers
  (setq ido-create-new-buffer 'always)
  (setq ido-enable-flex-maching t)
  (setq ido-everywhere t)
  (setq ibuffer-expert t)
  ;; Enable ido
  (ido-mode 1)

Electric

  ;; Make return key also do indent of previous line
  (electric-indent-mode 1)
  (setq electric-pair-pairs '(
							  (?\( . ?\))
							  (?\[ . ?\])
							  ))
  (electric-pair-mode 1)

File Backups

File auto-saves, backups, tramps.

  (setq emacs-cache (concat (getenv "XDG_CACHE_HOME") "/emacs"))
  (unless (file-directory-p emacs-cache)
	(make-directory emacs-cache t))
  ;https://emacs.stackexchange.com/questions/33/put-all-backups-into-one-backup-folder
  (setq backup-directory-alist `((".*" . ,emacs-cache))
		auto-save-file-name-transforms `((".*" ,(concat emacs-cache "") t))
		auto-save-list-file-prefix (concat emacs-cache "/.saves-")
		tramp-backup-directory-alist `((".*" . ,emacs-cache))
		tramp-auto-save-directory emacs-cache)
  (setq create-lockfiles nil   ; Disable lockfiles (.#)
		backup-by-copying t    ; Don't cobber symlinks
		delete-old-versions t  ; Cleanup backups
		version-control t      ; Use version numbers on backups
		kept-new-versions 5    ; Backups to keep
		kept-old-versions 2)   ; ,,

Hide Elements

  (menu-bar-mode 0)
  (scroll-bar-mode 0)
  (tool-bar-mode 0)
  (tooltip-mode 0)
  (fringe-mode 0)
  (blink-cursor-mode 0)

  (setq inhibit-startup-message t)
  (setq initial-scratch-message nil)
  (setq ring-bell-function 'ignore)

Org

  ;; Org
  (with-eval-after-load 'org
	(add-to-list 'org-structure-template-alist
				 '("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC")))

  (setq org-ellipsis " ↴")
  (setq org-src-fontify-natively t)
  (setq org-src-window-setup 'current-window)
  (setq org-latex-toc-command "\\newpage \\tableofcontents \\newpage")
  ;; Enable syntax highlighting when exporting to .pdf
  ;; Include latex-exporter
  (with-eval-after-load 'ox-latex
	;; Add minted to the list of packages to insert in every LaTeX header
	(add-to-list 'org-latex-packages-alist '("" "minted"))
	;; Define how minted is added to source code
	(setq org-latex-listings 'minted)
	(setq org-latex-minted-options
		  '(("frame" "lines") ("linenos=true")))
	;; Append -shell-escape to every element in org-latex-pdf-process
	(setq org-latex-pdf-process
		  (mapcar
		   (lambda (s)
			 (if (not (string-match-p "-shell-escape" s))
				 (replace-regexp-in-string "%latex " "%latex -shell-escape " s)
			   s))
		   org-latex-pdf-process)))

Tabs

  ;; Tabs
  (setq-default tab-width 4
				indent-tabs-mode t)

  ;; C/C++-like languages formatting style
  ;https://www.emacswiki.org/emacs/IndentingC
  (setq-default c-basic-offset 4
				c-default-style "linux")

UTF-8

Set UTF-8 encoding as default.

  (prefer-coding-system 'utf-8-unix)
  (setq locale-coding-system 'utf-8-unix)
  ;; Default also sets keyboard and terminal coding system
  (set-default-coding-systems 'utf-8-unix)
  (set-buffer-file-coding-system 'utf-8-unix)
  (set-file-name-coding-system 'utf-8-unix)
  (set-selection-coding-system 'utf-8-unix)

Functions

General

Functions that only use built-in Emacs functionality.

  (defun config-visit ()
	"Config edit."
	(interactive)
	(find-file "~/.emacs.d/config.org"))

  (defun config-reload ()
	"Config reload."
	(interactive)
	(org-babel-load-file (expand-file-name "~/.emacs.d/config.org")))

  (defun display-startup-echo-area-message ()
	"Hide default startup message."
	(message ""))

  (defun split-follow-horizontally ()
	"Split and follow window."
	(interactive)
	(split-window-below)
	(other-window 1))
  (defun split-follow-vertically ()
	"Split and follow window."
	(interactive)
	(split-window-right)
	(other-window 1))

  (defun find-project-root ()
	"Returns root of the project, determined by .git/, default-directory otherwise."
	(let ((search-directory (locate-dominating-file "." ".git")))
	  (if search-directory
		  search-directory
		default-directory))
	)

  (defun find-file-in-project-root ()
	"Find file in project root."
	(interactive)
	(let ((default-directory (find-project-root)))
	  (call-interactively 'find-file)))


  ;; https://emacsredux.com/blog/2013/05/04/rename-file-and-buffer/
  (defun rename-file-and-buffer ()
	"Rename the current buffer and file it is visiting."
	(interactive)
	(let ((filename (buffer-file-name)))
	  (if (not (and filename (file-exists-p filename)))
		  (message "Buffer is not visiting a file!")
		(let ((new-name (read-file-name "New name: " filename)))
		  (cond
		   ((vc-backend filename) (vc-rename-file filename new-name))
		   (t
			(rename-file filename new-name t)
			(set-visited-file-name new-name t t)))))))

  ;; https://emacsredux.com/blog/2013/04/21/edit-files-as-root/
  (defun sudo-edit (&optional arg)
	"Edit currently visited file as root.

  With a prefix ARG prompt for a file to visit.
  Will also prompt for a file to visit if current
  buffer is not visiting a file."
	(interactive "P")
	(if (or arg (not buffer-file-name))
		(find-file (concat "/sudo:root@localhost:"
						   (read-file-name "Find file(as root): ")))
	  (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))

Package

Functions that use package functionality.

  (defun centaur-tabs-buffer-groups ()
	"Organize tabs into groups."
	(list
	 (cond
	  ((string-equal "*" (substring (buffer-name) 0 1)) "Emacs")
	  ((derived-mode-p 'dired-mode) "Dired")
	  ((memq major-mode '(org-mode
						  org-agenda-mode
						  diary-mode
						  emacs-lisp-mode)) "OrgMode")
	  (t "User"))))

  (defun neotree-toggle-in-project-root ()
	"Toggle Neotree in project root."
	(interactive)
	(let ((default-directory (find-project-root)))
	  (call-interactively 'neotree-toggle)))

Advice and Aliases

Advice

Define default terminal option.

  (defvar terminal-shell "/bin/zsh")
  (defadvice ansi-term (before force-bash)
	(interactive (list terminal-shell)))
  (ad-activate 'ansi-term)

Aliases

General

Make confirm easier, by just pressing y/n.

  (defalias 'yes-or-no-p 'y-or-n-p)

Package

Evil command aliases.

  (with-eval-after-load 'evil-ex
    (evil-ex-define-cmd "W" "w")
    (evil-ex-define-cmd "Q" "q")
    (evil-ex-define-cmd "WQ" "wq")
    (evil-ex-define-cmd "Wq" "wq"))

Hooks

  ;; Delete trailing whitespace
  (add-hook 'before-save-hook 'delete-trailing-whitespace)

  ;; Highlight parentheses
  (add-hook 'prog-mode-hook 'show-paren-mode)

  ;; C++ // style comments in c-mode
  (add-hook 'c-mode-hook (lambda () (c-toggle-comment-style 0)))

Key Bindings

Useful links:
Mastering Emacs key bindings
use-package bind key
GNU remapping commands
GNU binding combinations of modifiers

Disable default

  (with-eval-after-load 'org
	(define-key org-mode-map (kbd "M-h") nil)
	(define-key org-mode-map (kbd "C-M-h") nil))

  (with-eval-after-load 'cc-mode
	(define-key c-mode-base-map (kbd "C-M-h") nil))

Default

  ;; Buffers
  (global-set-key (kbd "C-x b") 'ido-switch-buffer)
  (global-set-key (kbd "C-x C-b") 'ibuffer)
  (global-set-key (kbd "M-w") 'kill-this-buffer)

  ;; Config edit/reload
  (global-set-key (kbd "C-c e") 'config-visit)
  (global-set-key (kbd "C-c r") 'config-reload)

  ;; Split and follow window
  (global-set-key (kbd "C-x 2") 'split-follow-horizontally)
  (global-set-key (kbd "C-x 3") 'split-follow-vertically)

  ;; Find file
  (global-set-key (kbd "C-x C-f") 'find-file-in-project-root)

  ;; Terminal
  (global-set-key (kbd "<s-backspace>") 'ansi-term)

Disable package

Disable spacebar in evil motion.

  (with-eval-after-load 'evil-states
	(define-key evil-motion-state-map (kbd "<SPC>") nil))

Package

  ;; Avy
  (global-set-key (kbd "M-s") 'avy-goto-char-timer)

  ;; Buffers
  (global-set-key (kbd "M-h") 'centaur-tabs-backward-tab)
  (global-set-key (kbd "M-l") 'centaur-tabs-forward-tab)
  (global-set-key (kbd "C-M-h") 'centaur-tabs-move-current-tab-to-left)
  (global-set-key (kbd "C-M-l") 'centaur-tabs-move-current-tab-to-right)

  ;; Company completion selection
  (with-eval-after-load 'company
	(define-key company-active-map (kbd "M-n") nil)
	(define-key company-active-map (kbd "M-p") nil)
	(define-key company-active-map (kbd "M-h") #'company-abort)
	(define-key company-active-map (kbd "M-j") #'company-select-next)
	(define-key company-active-map (kbd "M-k") #'company-select-previous)
	(define-key company-active-map (kbd "M-l") #'company-complete-selection)
	(define-key company-active-map (kbd "<escape>") #'company-abort))
  ;https://github.com/company-mode/company-mode/blob/master/company.el#L661

  ;; Evil command history selection
  (with-eval-after-load 'evil-ex
	(define-key evil-ex-completion-map (kbd "M-h") 'abort-recursive-edit)
	(define-key evil-ex-completion-map (kbd "M-j") #'next-complete-history-element)
	(define-key evil-ex-completion-map (kbd "M-k") #'previous-complete-history-element)
	(define-key evil-ex-completion-map (kbd "M-l") 'exit-minibuffer))

  ; Overwrite evil keymaps
  ;(evil-global-set-key 'motion (kbd "C-w") 'kill-this-buffer)
  ;(evil-define-key 'motion 'global (kbd "C-w") 'kill-this-buffer)
  ;(define-key evil-motion-state-map (kbd "C-w") 'kill-this-buffer) ; @Todo test this with nil
  ;https://github.com/noctuid/evil-guide#global-keybindings-and-evil-states

  ;; Neotree
  (with-eval-after-load 'evil-states
	(define-key evil-normal-state-map (kbd "C-n") 'neotree-toggle-in-project-root))

  ;; Smex
  (global-set-key (kbd "M-x") 'smex)
  (global-set-key (kbd "M-X") 'smex-major-mode-commands)

Leader

General.el leader key binds.

  (with-eval-after-load 'general
	(general-create-definer space-leader
	  :prefix "SPC"
	  :non-normal-prefix "M-SPC"
	  :states '(normal visual insert motion emacs))

	(general-create-definer comma-leader
	  :prefix ","
	  :states '(normal visual))

	(space-leader
	  "SPC" 'smex

	  ;; Buffer
	  "b"  '(:ignore t :which-key "buffer")
	  "b B" 'ibuffer
	  "b b" 'ido-switch-buffer
	  "b d" 'kill-this-buffer
	  "b h" 'previous-buffer
	  "b l" 'next-buffer
	  "b r" 'revert-buffer

	  ;; Comments / config
	  "c"   '(:ignore t :which-key "comments/config")
	  "c c" 'evilnc-comment-or-uncomment-lines
	  "c p" 'evilnc-comment-or-uncomment-paragraphs
	  "c r" 'config-reload
	  "c v" 'config-visit
	  "c y" 'evilnc-comment-and-kill-ring-save

	  ;; Find file
	  "f"   '(:ignore t :which-key "file")
	  "f f" 'find-file-in-project-root
	  "f r" 'rename-file-and-buffer
	  "f s" 'save-buffer

	  ;; Tabs
	  "h" 'centaur-tabs-backward-group
	  "j" 'centaur-tabs-select-end-tab
	  "k" 'centaur-tabs-select-beg-tab
	  "l" 'centaur-tabs-forward-group

	  ;; Neotree
	  "n" 'neotree-toggle-in-project-root

	  ;; Quit
	  "q"   '(:ignore t :which-key "quit")
	  "q q" 'kill-emacs
	  "q d" 'delete-frame
	  "q o" 'delete-other-frame

	  ;; Avy
	  "s" 'avy-goto-char-timer

	  ;; Window
	  "w"     '(:ignore t :which-key "window")
	  "w d"   'delete-window
	  "w h"   'evil-window-left
	  "w j"   'evil-window-down
	  "w k"   'evil-window-up
	  "w l"   'evil-window-right
	  "w o"   'delete-other-windows
	  "w s"   '(:ignore t :which-key "split")
	  "w s h" 'split-follow-horizontally
	  "w s v" 'split-follow-vertically
	  "w w"   'other-window

	  "x" 'smex-major-mode-commands
	  ))

Source: https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-evil.el#L712 https://github.com/suyashbire1/emacs.d/blob/master/init.el

Notes

Org mode keybinds

  • <C-return> = org-insert-heading-respect-content (create new node)
  • <C-x n s> = org-narrow-to-subtree
  • <C-x n w> = widen
  • <S-left/right> = org-shiftleft/org-shiftright (cycle to next todo keyword)
  • <S-up/down> = org-shiftup/org-shiftdown (cycle todo priority)
  • <M-S-return> = org-insert-todo-heading (add todo item)