mirror of
https://github.com/Foltik/dotfiles
synced 2024-11-24 12:26:05 -05:00
1157 lines
34 KiB
Org Mode
1157 lines
34 KiB
Org Mode
* Packaging
|
||
** Package.el
|
||
[[http://wikemacs.org/wiki/Package.el][Package.el]] is the built-in package manager in Emacs. This is where the fun begins.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'package)
|
||
(setq package-archives
|
||
'(("gnu" . "https://elpa.gnu.org/packages/")
|
||
("melpa" . "https://melpa.org/packages/")
|
||
("melpa-stable" . "https://stable.melpa.org/packages/")
|
||
("marmalade" . "https://marmalade-repo.org/packages/")
|
||
("org" . "https://orgmode.org/elpa/")))
|
||
(setq package-enable-at-startup nil)
|
||
(package-initialize)
|
||
#+END_SRC
|
||
** use-package
|
||
[[https://github.com/jwiegley/use-package][use-package]] is a nifty macro that interfaces with =Package.el=, keeping package-specific
|
||
configuration all in once place. It's pretty much the basis of this entire config.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(unless (package-installed-p 'use-package)
|
||
(package-refresh-contents)
|
||
(package-install 'use-package))
|
||
|
||
(eval-when-compile
|
||
(require 'use-package))
|
||
|
||
(setq use-package-compute-statistics t)
|
||
(setq use-package-always-ensure t)
|
||
(setq use-package-always-pin "melpa")
|
||
(setq use-package-verbose t)
|
||
#+END_SRC
|
||
*** Custom Keywords
|
||
A few useful =:keyword= macros that extend the vanilla =use-package= functionality.
|
||
**** :company
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'derived)
|
||
|
||
(defun use-package-company-normalize (name keyword args)
|
||
"Normalize the KEYWORD with NAME :company with arguments ARGS into a list of pairs for the handler."
|
||
(use-package-as-one (symbol-name keyword) args
|
||
(lambda (label arg)
|
||
(unless (or (consp arg) (use-package-non-nil-symbolp arg))
|
||
(use-package-error
|
||
(concat
|
||
label
|
||
"<symbol> or "
|
||
"(<symbol or list of symbols> . <symbol or function>) or "
|
||
"a list of these")))
|
||
(use-package-normalize-pairs
|
||
(lambda (k)
|
||
(or (use-package-non-nil-symbolp k)
|
||
(and (consp k)
|
||
(not (cdr (last k)))
|
||
(seq-every-p 'use-package-non-nil-symbolp k))))
|
||
#'use-package-recognize-function
|
||
name label arg))))
|
||
|
||
;;;###autoload
|
||
(defun use-package-company-handler (name _keyword args rest state)
|
||
"Generate a function and hook from each pair in NAME ARGS for the keyword with NAME :company, appending the forms to the ‘use-package’ declaration specified by REST and STATE."
|
||
(use-package-concat
|
||
(use-package-process-keywords name rest state)
|
||
(mapcan
|
||
(lambda (def)
|
||
(let ((modes (car def))
|
||
(backend (cdr def))
|
||
(fun (intern (concat "use-package-company-add-" (symbol-name (cdr def))))))
|
||
(when backend
|
||
(append
|
||
`((defun ,fun ()
|
||
(setq-local company-backends
|
||
(append company-backends '(,backend)))))
|
||
(mapcar
|
||
(lambda (mode)
|
||
`(add-hook
|
||
',(derived-mode-hook-name mode)
|
||
#',fun))
|
||
(if (use-package-non-nil-symbolp modes) (list modes) modes))))))
|
||
(use-package-normalize-commands args))))
|
||
|
||
(defalias 'use-package-normalize/:company 'use-package-company-normalize)
|
||
(defalias 'use-package-handler/:company 'use-package-company-handler)
|
||
(defalias 'use-package-autoloads/:company 'use-package-autoloads-mode)
|
||
|
||
(setq use-package-keywords
|
||
(let ((idx (+ 1 (cl-position :hook use-package-keywords))))
|
||
(append
|
||
(seq-subseq use-package-keywords 0 idx)
|
||
(list :company)
|
||
(nthcdr idx use-package-keywords))))
|
||
#+END_SRC
|
||
* Keybinds
|
||
** which-key
|
||
[[https://github.com/justbur/emacs-which-key][which-key]] displays a popup in the minibuffer that shows
|
||
keybindings following incomplete commands.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package which-key
|
||
:diminish
|
||
:config
|
||
(which-key-mode))
|
||
#+END_SRC
|
||
** General
|
||
[[https://github.com/noctuid/general.el][General]] is an excellent keybind manager that adds *tons* of useful macros.
|
||
Also set up a leader key and prefixes, like =\= in Vim.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package general
|
||
:config
|
||
(general-create-definer jf-leader-def
|
||
:keymaps 'override
|
||
:states '(normal insert emacs)
|
||
:prefix "SPC"
|
||
:non-normal-prefix "M-SPC")
|
||
|
||
(defun jf-create-wk-prefix (desc)
|
||
"Helper for creating which-key prefix descriptions.
|
||
Bind to a key with general to make which-key show DESC
|
||
as the prefix's description"
|
||
`(:ignore t :wk ,desc))
|
||
|
||
(defmacro jf-create-definers (definitions)
|
||
"A wrapper for general-create-definer.
|
||
For every pair in DEFINITIONS, creates a leader
|
||
with name jf-NAME-def and keybind SPC KEY or M-SPC KEY in normal mode."
|
||
`(progn
|
||
,@(mapcan
|
||
(lambda (def)
|
||
(let ((key (car def))
|
||
(name (cdr def)))
|
||
`((general-create-definer ,(intern (concat "jf-" name "-def"))
|
||
:keymaps 'override
|
||
:states '(normal insert emacs)
|
||
:prefix ,(concat "SPC " key)
|
||
:non-normal-prefix ,(concat "M-SPC " key))
|
||
(jf-leader-def ,key ',(jf-create-wk-prefix name)))))
|
||
definitions)))
|
||
|
||
(jf-create-definers
|
||
(("a" . "apps")
|
||
("b" . "buffers")
|
||
("f" . "files")
|
||
("g" . "git")
|
||
("h" . "help")
|
||
("m" . "major")
|
||
("o" . "org")
|
||
("p" . "projects")
|
||
("w" . "windows"))))
|
||
#+END_SRC
|
||
* Vim Emulation
|
||
** Evil
|
||
[[https://github.com/emacs-evil/evil][Evil]] is pretty much the entirety of Vim in Emacs.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package evil
|
||
:diminish undo-tree-mode
|
||
|
||
:preface
|
||
(defun jf-window-split ()
|
||
(interactive)
|
||
(evil-window-split)
|
||
(evil-window-down 1))
|
||
(defun jf-window-vsplit ()
|
||
(interactive)
|
||
(evil-window-vsplit)
|
||
(evil-window-right 1))
|
||
|
||
:config
|
||
(evil-mode t)
|
||
|
||
(jf-windows-def
|
||
"-" #'jf-window-split
|
||
"=" #'jf-window-vsplit
|
||
"b" #'balance-windows
|
||
"H" #'evil-window-far-left
|
||
"J" #'evil-window-bottom
|
||
"K" #'evil-window-top
|
||
"L" #'evil-window-far-right
|
||
"h" #'evil-window-left
|
||
"j" #'evil-window-right
|
||
"k" #'evil-window-down
|
||
"l" #'evil-window-right
|
||
"o" #'other-frame)
|
||
|
||
:custom
|
||
(evil-want-integration t)
|
||
(evil-want-keybinding nil)
|
||
(evil-want-fine-undo t))
|
||
#+END_SRC
|
||
** Evil Collection
|
||
[[https://github.com/emacs-evil/evil-collection][Evil Collection]] adds Evil bindings for all the parts of Emacs that Evil
|
||
doesn't cover properly by default.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package evil-collection
|
||
:after evil
|
||
:config
|
||
(evil-collection-init
|
||
'(calendar
|
||
cmake-mode
|
||
company
|
||
custom
|
||
debug
|
||
dired
|
||
doc-view
|
||
elisp-mode
|
||
elisp-refs
|
||
eshell
|
||
eval-sexp-fu
|
||
flycheck
|
||
flymake
|
||
grep
|
||
help
|
||
ibuffer
|
||
image
|
||
image-dired
|
||
info
|
||
ivy
|
||
js2-mode
|
||
log-view
|
||
man
|
||
neotree
|
||
python
|
||
racer
|
||
realgud
|
||
which-key)))
|
||
#+END_SRC
|
||
** Evil Extensions
|
||
*** Avy
|
||
An enhanced version of =f= in Vim.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package avy
|
||
:general
|
||
(:keymaps 'override
|
||
:states 'normal
|
||
"C-f" 'avy-goto-char-in-line
|
||
"C-F" 'avy-goto-char))
|
||
#+END_SRC
|
||
*** Subword
|
||
Make boundaries between words in camelCase act as separate words for evil motions.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package subword
|
||
:init
|
||
(define-category ?U "Uppercase")
|
||
(define-category ?u "Lowercase")
|
||
(modify-category-entry (cons ?A ?Z) ?U)
|
||
(modify-category-entry (cons ?a ?z) ?u)
|
||
|
||
:config
|
||
(push '(?u . ?U) evil-cjk-word-separating-categories))
|
||
#+END_SRC
|
||
*** evil-surround
|
||
Use =S= and a delimiter to surround in visual mode.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package evil-surround
|
||
:after evil
|
||
:diminish
|
||
:config
|
||
(global-evil-surround-mode 1))
|
||
#+END_SRC
|
||
* Emacs
|
||
** Defaults
|
||
*** Configuration Editing
|
||
Add functions for editing and reloading the Emacs config files.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun jf-edit-config ()
|
||
(interactive)
|
||
(find-file jf-config-file))
|
||
|
||
(defun jf-edit-init ()
|
||
(interactive)
|
||
(find-file jf-init-file))
|
||
|
||
(defun jf-reload-config ()
|
||
(interactive)
|
||
(org-babel-load-file jf-config-file))
|
||
|
||
(jf-files-def
|
||
"e" (jf-create-wk-prefix "emacs files")
|
||
"ec" #'jf-edit-config
|
||
"ei" #'jf-edit-init
|
||
"er" #'jf-reload-config)
|
||
#+END_SRC
|
||
*** Add to Load Path
|
||
Create and add a folder to the load path for local lisp files.
|
||
The folder itself and all descendants will be added to the path.
|
||
These packages will take precedence over other libraries with the same name.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(unless (file-exists-p jf-load-path)
|
||
(make-directory jf-load-path))
|
||
|
||
(let ((default-directory jf-load-path))
|
||
(setq load-path
|
||
(append
|
||
(let ((load-path (copy-sequence load-path)))
|
||
(append
|
||
(copy-sequence (normal-top-level-add-to-load-path '(".")))
|
||
(normal-top-level-add-subdirs-to-load-path)))
|
||
load-path)))
|
||
#+END_SRC
|
||
*** File Not Found Functions
|
||
Offer to create parent folders when a file is opened
|
||
Offer to create nonexistant parent directories.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun jf-create-nonexistant-directories ()
|
||
(let ((parent-directory (file-name-directory buffer-file-name)))
|
||
(when (and (not (file-exists-p parent-directory))
|
||
(y-or-n-p (format "Directory `%s' does not exist. Create it?" parent-directory)))
|
||
(make-directory parent-directory t)))) ; last argument specifies to behave like `mkdir -p'
|
||
|
||
(add-to-list 'find-file-not-found-functions #'jf-create-nonexistant-directories)
|
||
#+END_SRC
|
||
*** Customize Location
|
||
Make changes in =M-x customize= go somewhere other than being schlunked into =init.el=.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq custom-file (concat user-emacs-directory "_customize.el"))
|
||
(load custom-file t)
|
||
#+END_SRC
|
||
*** Disable Bell
|
||
Shut up, emacs.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq ring-bell-function #'ignore)
|
||
#+END_SRC
|
||
*** Shorter Prompts
|
||
Make =yes-or-no= prompts ask for =y-or-n= instead. Saves loads of time™.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defalias 'yes-or-no-p #'y-or-n-p)
|
||
#+END_SRC
|
||
*** Move Backup Files
|
||
By default, emacs gunks up every folder with =file~= backups
|
||
and =#file#= lockfiles. Schlunk them all in =/tmp= instead.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq backup-directory-alist
|
||
`((".*" . ,temporary-file-directory)))
|
||
(setq auto-save-file-name-transforms
|
||
`((".*" ,temporary-file-directory t)))
|
||
#+END_SRC
|
||
*** Secure auth-source
|
||
GPG encrypt stored auth tokens from [[https://www.gnu.org/software/emacs/manual/html_mono/auth.html][auth-source]] instead of storing them in plaintext.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq auth-sources '("~/.emacs.d/authinfo.gpg"))
|
||
#+END_SRC
|
||
*** Use UTF-8
|
||
Pleeeease default to UTF-8, Emacs.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq locale-coding-system 'utf-8)
|
||
(set-terminal-coding-system 'utf-8)
|
||
(set-keyboard-coding-system 'utf-8)
|
||
(set-selection-coding-system 'utf-8)
|
||
(prefer-coding-system 'utf-8)
|
||
#+END_SRC
|
||
*** Trash when Deleting
|
||
Don't permanently delete stuff unless asked.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq delete-by-moving-to-trash t)
|
||
#+END_SRC
|
||
*** Open Compressed Files
|
||
...automatically.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq auto-compression-mode t)
|
||
#+END_SRC
|
||
*** Save Minibuffer History
|
||
#+BEGIN_SRC emacs-lisp
|
||
(savehist-mode 1)
|
||
(setq history-length 1000)
|
||
#+END_SRC
|
||
*** Double Spaces
|
||
Why sentences would need double spaces to end I do not know.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(set-default 'sentence-end-double-space nil)
|
||
#+END_SRC
|
||
*** Eval Print Level
|
||
Print more stuff when running =C-x C-e= or =(eval-last-sexp)=
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq eval-expression-print-level 100)
|
||
#+END_SRC
|
||
*** GC in Minibuffer
|
||
Don't garbage collect while the minibuffer is open, as heavy
|
||
things like completion and searches are happening and will
|
||
slow down with many garbage collections.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-hook 'minibuffer-setup-hook #'jf-inhibit-gc)
|
||
(add-hook 'minibuffer-exit-hook #'jf-resume-gc)
|
||
#+END_SRC
|
||
** UI
|
||
*** Font
|
||
Engage a nice coding font.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(add-to-list 'default-frame-alist '(font . "Fira Code 12"))
|
||
(set-face-attribute 'default t :font "Fira Code 12")
|
||
#+END_SRC
|
||
*** Menu Bar
|
||
Disable the useless cruft at the top of the screen.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(menu-bar-mode -1)
|
||
(tool-bar-mode -1)
|
||
(scroll-bar-mode -1)
|
||
#+END_SRC
|
||
*** Modeline
|
||
**** Diminish
|
||
Adds support for =:diminish= in use-package declarations, which hides a mode from the modeline.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package diminish)
|
||
#+END_SRC
|
||
**** Column Number
|
||
Show line and column numbers in the modeline.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq line-number-mode t)
|
||
(setq column-number-mode t)
|
||
#+END_SRC
|
||
*** Line Numbers
|
||
Use the default emacs relative line numbers, but switch to absolute lines when in insert mode.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package nlinum-relative
|
||
:config
|
||
(nlinum-relative-setup-evil)
|
||
:hook (prog-mode . nlinum-relative-mode))
|
||
#+END_SRC
|
||
|
||
*** Show Matching Parens
|
||
Shows matching parenthesis
|
||
#+BEGIN_SRC emacs-lisp
|
||
(require 'paren)
|
||
(setq show-paren-delay 0)
|
||
(show-paren-mode)
|
||
#+END_SRC
|
||
*** Scrolling
|
||
Scroll smooth-ish-ly instead of jarring jumps.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package smooth-scroll
|
||
:config
|
||
(smooth-scroll-mode t))
|
||
#+END_SRC
|
||
*** Dashboard
|
||
Show a cool custom dashboard buffer on startup.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package dashboard
|
||
:diminish page-break-lines-mode
|
||
:config
|
||
(dashboard-setup-startup-hook)
|
||
(setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
|
||
|
||
:custom
|
||
(dashboard-startup-banner 'logo)
|
||
(dashboard-banner-logo-title
|
||
(format "Welcome to Electronic Macs. Ready in %.2f seconds with %d GCs."
|
||
(float-time (time-subtract after-init-time before-init-time))
|
||
gcs-done))
|
||
(dashboard-items
|
||
'((recents . 5)
|
||
(agenda)
|
||
(bookmarks . 5)
|
||
(registers . 5))))
|
||
#+END_SRC
|
||
** Themes
|
||
*** pywal
|
||
Fancy dynamic color scheme generation from desktop wallpapers.
|
||
Requires additional setup on the machine itself.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar jf-theme-pywal-path "~/.cache/wal/colors.el" "Path to the colorscheme generated by pywal.")
|
||
|
||
(defun jf-theme-pywal ()
|
||
(load-file jf-theme-pywal-path))
|
||
|
||
(when (eq 'jf-theme 'jf-theme-pywal)
|
||
(require 'filenotify)
|
||
(file-notify-add-watch jf-theme-pywal-path '(change) #'jf-theme-pywal))
|
||
#+END_SRC
|
||
*** spacemacs
|
||
This theme is pretty fancy and has lots of supported modes.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(unless (package-installed-p 'spacemacs-theme)
|
||
(package-install 'spacemacs-theme))
|
||
|
||
(defun jf-theme-spacemacs ()
|
||
(load-theme 'spacemacs-dark))
|
||
#+END_SRC
|
||
*** Transparency
|
||
Sets the window's transparency, to better admire choice wallpapers.
|
||
The first number in the alpha section applies when the window is
|
||
active, the second when it's inactive.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(set-frame-parameter (selected-frame) 'alpha 85)
|
||
(add-to-list 'default-frame-alist '(alpha . 85))
|
||
#+END_SRC
|
||
|
||
*** Helpers
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar jf-theme #'jf-theme-pywal "Theme function to call.")
|
||
|
||
(defun jf-apply-theme ()
|
||
"Apply the current theme as set by jf-theme."
|
||
(funcall jf-theme))
|
||
|
||
(jf-apply-theme)
|
||
#+END_SRC
|
||
* Organization
|
||
** Capture Templates
|
||
All capture templates, from tasks to bookmarks.
|
||
*** Refile Targets
|
||
Goodize the refiling targets to allow refiling to arbitrary subtrees.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun jf-org-capture-refile ()
|
||
(interactive)
|
||
(setq-local org-refile-targets '((nil :maxlevel . 5)))
|
||
(setq-local org-refile-use-outline-path t)
|
||
(org-refile))
|
||
#+END_SRC
|
||
*** Tasks
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-org-capture-task-templates
|
||
'(("t" "Todo")
|
||
("tg" "General" entry
|
||
(file+headline "notes.org" "Todo")
|
||
"** TODO %^{todo}\nNotes: %?\n")
|
||
("tt" "General (Date)" entry
|
||
(file+olp+datetree "notes.org")
|
||
"*** TODO %^{todo}\nDue: %^t\nNotes: %?\n")
|
||
("tT" "General (Date+Time)" entry
|
||
(file+olp+datetree "notes.org")
|
||
"*** TODO %^{todo}\nDue: %^T\nNotes: %?\n")
|
||
("ts" "School (Date)" entry
|
||
(file+olp+datetree "notes.org")
|
||
"*** TODO %^{todo}\nDue: %^t\nClass: %^{class}\nNotes: %?\n")
|
||
("tS" "School (Date+Time)" entry
|
||
(file+olp+datetree "notes.org")
|
||
"*** TODO %^{todo}\nDue: %^T\nClass: %^{class}\nNotes: %?\n")))
|
||
#+END_SRC
|
||
*** Bookmarks
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-org-capture-bookmark-templates
|
||
'(("b" "Bookmark" entry
|
||
(file+headline "links.org" "Unsorted Links")
|
||
"** [[%^{link}][%^{name}]]\nCreated: %U\nAbout: %^{description}%?\n")))
|
||
#+END_SRC
|
||
*** Personal
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-org-capture-personal-templates
|
||
'(("j" "Journal")
|
||
("jj" "Journal Entry" entry
|
||
(file+olp+datetree "journal.org")
|
||
"**** Today's Events\n%?")
|
||
("jt" "Thoughts" entry
|
||
(file+headline "notes.org" "Thoughts")
|
||
"** %^{summary}\n%U\n%?")
|
||
("jd" "Dream Journal Entry" entry
|
||
(file+olp+datetree "dreams.org")
|
||
"**** Dream\n%?")))
|
||
#+END_SRC
|
||
*** Protocol
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-org-capture-protocol-templates
|
||
'(("w" "Website" entry
|
||
(file+headline "sites.org" "Unsorted Sites")
|
||
"** [[%:link][%:description%?]]\nCreated: %U\nAbout: %^{description}%?\n%:initial")))
|
||
#+END_SRC
|
||
*** All
|
||
Tie it all together.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-org-capture-templates
|
||
(append
|
||
jf-org-capture-task-templates
|
||
jf-org-capture-personal-templates
|
||
jf-org-capture-bookmark-templates
|
||
jf-org-capture-protocol-templates))
|
||
#+END_SRC
|
||
** Structure Templates
|
||
Defines expansions with =<= followed by a string in org-mode.
|
||
*** Source Blocks
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-org-source-structure-templates
|
||
'(("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC")))
|
||
#+END_SRC
|
||
*** All
|
||
Tie it all together.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-org-structure-templates
|
||
(append
|
||
jf-org-source-structure-templates))
|
||
#+END_SRC
|
||
|
||
** Org-mode
|
||
Keep org-mode up to date straight from the cow's utters.
|
||
If the manual is not on your computer, it's [[https://orgmode.org/manual/][here]].
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org
|
||
:pin org
|
||
:mode ("\\.org\\'" . org-mode)
|
||
:hook ((org-mode . org-indent-mode)
|
||
(org-capture-mode . evil-insert-state))
|
||
|
||
:general
|
||
(jf-major-def
|
||
:keymaps 'org-mode-map
|
||
"e" 'org-export-dispatch
|
||
"a" 'org-attach)
|
||
(jf-org-def
|
||
"a" 'org-agenda
|
||
"c" 'org-capture
|
||
"l" 'org-store-link
|
||
"b" 'org-switchb
|
||
"r" 'jf-org-capture-refile)
|
||
:custom
|
||
(org-directory "~/Documents/org")
|
||
(org-agenda-files '("~/Documents/org/"))
|
||
(org-default-notes-file "notes.org")
|
||
(org-agenda-include-diary t)
|
||
(org-src-window-setup 'current-window "Edit source code in the current window")
|
||
(org-src-fontify-natively t "Highlight syntax in source blocks")
|
||
(org-latex-to-pdf-process '("latexmk -f pdf %f") "Use pdflatex for export")
|
||
(org-capture-templates jf-org-capture-templates)
|
||
(org-structure-template-alist (append org-structure-template-alist jf-org-structure-templates)))
|
||
#+END_SRC
|
||
** Pretty org-mode bullets
|
||
Make bullets look choice
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package org-bullets
|
||
:hook (org-mode . org-bullets-mode))
|
||
#+END_SRC
|
||
* Communication
|
||
* Web
|
||
* Tools
|
||
** Fuzzy Matching
|
||
Most facilities are provided by [[https://github.com/abo-abo/swiper][Ivy]] and friends, which build on existing emacs commands.
|
||
*** Smex
|
||
While the actual smex command is not in use,
|
||
counsel-M-x will use it for sorting by usage.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package smex)
|
||
#+END_SRC
|
||
*** Ivy
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package ivy
|
||
:init
|
||
(defun jf-kill-current-buffer ()
|
||
(interactive)
|
||
(kill-buffer (current-buffer)))
|
||
(defun jf-kill-all-buffers ()
|
||
(interactive)
|
||
(seq-do 'kill-buffer (buffer-list)))
|
||
|
||
:general
|
||
(jf-buffers-def
|
||
"b" 'ivy-switch-buffer
|
||
"v" 'ivy-push-view
|
||
"V" 'ivy-pop-view
|
||
"c" 'jf-kill-current-buffer
|
||
"C" 'jf-kill-all-buffers)
|
||
|
||
:custom
|
||
(ivy-use-virtual-buffers t)
|
||
(ivy-count-format "%d/%d"))
|
||
#+END_SRC
|
||
*** Counsel
|
||
A collection of ivy enhanced versions of common Emacs commands.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package counsel
|
||
:general
|
||
("M-x" 'counsel-M-x)
|
||
(jf-leader-def
|
||
:states 'normal
|
||
"x" 'counsel-M-x)
|
||
(jf-files-def
|
||
"f" 'counsel-find-file)
|
||
(jf-help-def
|
||
"a" 'counsel-apropos
|
||
"f" 'counsel-describe-function
|
||
"k" 'counsel-descbinds
|
||
"l" 'counsel-find-library
|
||
"s" 'counsel-info-lookup-symbol
|
||
"u" 'counsel-unicode-char
|
||
"v" 'counsel-describe-variable))
|
||
#+END_SRC
|
||
*** Swiper
|
||
An ivy-ified replacement for isearch.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package swiper
|
||
:after evil
|
||
:general
|
||
(:keymaps 'override
|
||
:states 'normal
|
||
"/" 'swiper
|
||
"n" 'evil-search-previous
|
||
"N" 'evil-search-next))
|
||
#+END_SRC
|
||
|
||
** Neotree
|
||
A cool toggleable directory structure sidebar.
|
||
It needs icon fonts, installed with =M-x all-the-icons-install-fonts=.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package all-the-icons)
|
||
(use-package neotree
|
||
:after all-the-icons
|
||
:general
|
||
(jf-apps-def
|
||
"t" 'neotree-toggle)
|
||
:custom
|
||
(neo-theme (if (display-graphic-p) 'icons 'arrow)))
|
||
#+END_SRC
|
||
** Ranger
|
||
Brings the glory of [[https://github.com/ralesi/ranger.el][Ranger]] to Emacs.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package ranger
|
||
:commands (ranger deer))
|
||
#+END_SRC
|
||
** Sunshine
|
||
Allows retrieving OpenWeatherMap forecasts in the minibuffer.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package sunshine
|
||
:commands sunshine-forecast
|
||
:general
|
||
(jf-apps-def
|
||
"w" #'sunshine-forecast)
|
||
:custom
|
||
(sunshine-location "Piscataway, US")
|
||
(sunshine-units 'metric)
|
||
(sunshine-appid "7caf100277f14845e7f354c6590a09cb")
|
||
(sunshine-show-icons t))
|
||
#+END_SRC
|
||
* Programming
|
||
** Formatting
|
||
*** Indentation
|
||
Set some *sane* defaults
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-tab-width 4)
|
||
(setq-default python-indent-offset jf-tab-width)
|
||
(setq-default evil-shift-width jf-tab-width)
|
||
(setq-default c-basic-offset jf-tab-width)
|
||
; Disable annoying electric indent of previous lines
|
||
(setq-default electric-indent-inhibit t)
|
||
; Eat the whole tab when I press backspace
|
||
(setq backward-delete-char-untabify-method 'hungry)
|
||
#+END_SRC
|
||
Define some *useful* helper functions
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun jf-indent-tabs (width)
|
||
(interactive "nTab width: ")
|
||
(setq tab-width width)
|
||
(local-set-key (kbd "TAB") 'tab-to-tab-stop)
|
||
(setq indent-tabs-mode t))
|
||
|
||
(defun jf-indent-spaces (num)
|
||
(interactive "nNumber of spaces: ")
|
||
(setq tab-width num)
|
||
(setq indent-tabs-mode nil))
|
||
|
||
;; Default to 4 spaces
|
||
(add-hook 'prog-mode-hook #'jf-indent-4-spaces)
|
||
|
||
;; Define functions for every level of indent that might need hooking
|
||
(cl-macrolet
|
||
((jf-define-indent-funs (widths)
|
||
`(progn
|
||
,@(mapcan
|
||
(lambda (num)
|
||
`((defun ,(intern (concat "jf-indent-" (number-to-string num) "-spaces")) ()
|
||
(jf-indent-spaces ,num))
|
||
(defun ,(intern (concat "jf-indent-tabs-" (number-to-string num))) ()
|
||
(jf-indent-tabs ,num))))
|
||
widths))))
|
||
(jf-define-indent-funs (2 4 8)))
|
||
|
||
;; TODO: Replace with dedicated whitespace config
|
||
(setq whitespace-style '(face tabs tab-mark trailing))
|
||
(custom-set-faces
|
||
'(whitespace-tab ((t (:foreground "#636363")))))
|
||
|
||
;; Make tabs visible
|
||
(setq whitespace-display-mappings
|
||
'((tab-mark 9 [124 9] [92 9])))
|
||
|
||
(add-hook 'prog-mode-hook #'whitespace-mode)
|
||
#+END_SRC
|
||
*** Parentheses
|
||
**** Smartparens
|
||
[[https://github.com/Fuco1/smartparens][Smartparens]] handles parens for languages that aren't lispy.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package smartparens
|
||
:diminish
|
||
:commands smartparens-mode
|
||
:config
|
||
(require 'smartparens-config))
|
||
#+END_SRC
|
||
**** ParEdit
|
||
And [[https://www.emacswiki.org/emacs/ParEdit][ParEdit]] handles the rest.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package paredit
|
||
:diminish
|
||
:commands enable-paredit-mode)
|
||
#+END_SRC
|
||
**** Evil-Cleverparens
|
||
[[https://github.com/luxbock/evil-cleverparens][Evil-Cleverparens]] adds additional features to Evil all about
|
||
working with sexps, including keeping parens balanced when
|
||
using commands like =dd=.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package evil-cleverparens
|
||
:diminish
|
||
:commands evil-cleverparens-mode)
|
||
#+END_SRC
|
||
**** Activation
|
||
Pick a suitable parenthesis editing mode for the
|
||
current major mode when entering any prog-mode derivative.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun jf-paren-mode ()
|
||
(if (member major-mode '(emacs-lisp-mode
|
||
lisp-mode
|
||
lisp-interaction-mode
|
||
scheme-mode))
|
||
(enable-paredit-mode)
|
||
(smartparens-mode)))
|
||
|
||
(add-hook 'prog-mode-hook #'jf-paren-mode)
|
||
#+END_SRC
|
||
*** Whitespace
|
||
**** ws-butler
|
||
Unobtrusively cleans up whitespace before EOLs
|
||
as you edit, stopping the noisy commits generated
|
||
from blanket trimming entire files.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package ws-butler
|
||
:hook (prog-mode . ws-butler-mode))
|
||
#+END_SRC
|
||
*** pretty-mode
|
||
[[https://github.com/pretty-mode/pretty-mode][pretty-mode]] redisplays parts of the Emacs buffer as pretty symbols.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package pretty-mode
|
||
:hook (prog-mode . pretty-mode)
|
||
:config
|
||
(pretty-deactivate-groups '(:arithmetic
|
||
:sub-and-superscripts))
|
||
(pretty-activate-groups '(:equality
|
||
:ordering
|
||
:ordering-double
|
||
:ordering-triple
|
||
:arrows
|
||
:arrows-twoheaded
|
||
:punctuation
|
||
:logic
|
||
:sets)))
|
||
#+END_SRC
|
||
|
||
*** Prettify-Symbols-Mode
|
||
Allows custom unicode replacement of symbols. Fill in the gaps where
|
||
pretty-mode left off.
|
||
**** Python
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defun jf-prettify-python ()
|
||
(dolist (pair '(;; Syntax
|
||
("in" . #x2208)
|
||
("not in" . #x2209)
|
||
("return" . #x27fc)
|
||
("yield" . #x27fb)
|
||
("for" . #x2200)
|
||
;; Base Types
|
||
("int" . #x2124)
|
||
("float" . #x211d)
|
||
("str" . #x1d54a)
|
||
("True" . #x1d54b)
|
||
("False" . #x1d53d)))
|
||
(push pair prettify-symbols-alist)))
|
||
|
||
(add-hook 'python-mode-hook #'prettify-symbols-mode)
|
||
(add-hook 'python-mode-hook #'jf-prettify-python)
|
||
#+END_SRC
|
||
|
||
** Checkers
|
||
*** Flycheck
|
||
Flycheck highlights syntax errors in a few languages.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package flycheck
|
||
:hook (prog-mode . flycheck-mode))
|
||
#+END_SRC
|
||
*** Column 80 Highlight
|
||
Add a hotkey for highlighting column 80
|
||
and activate it in =prog-mode=
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package fill-column-indicator
|
||
:init
|
||
(setq fci-rule-use-dashes t)
|
||
(setq fci-rule-column 80)
|
||
:general
|
||
(jf-major-def
|
||
:keymaps 'prog-mode-map
|
||
"8" 'fci-mode))
|
||
#+END_SRC
|
||
|
||
** Completion
|
||
*** Company
|
||
Company auto-completes stuff in the buffer, and company-quickhelp shows
|
||
documentation popups when idling on a completion candidate.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package company
|
||
:hook (prog-mode . company-mode)
|
||
:general
|
||
(:keymaps 'company-active-map
|
||
"C-SPC" 'company-abort)
|
||
|
||
:custom
|
||
(company-maximum-prefix-length 2)
|
||
(company-idle-delay 0.2 "Decrease idle delay"))
|
||
|
||
(use-package company-quickhelp
|
||
:after company
|
||
:hook (company-mode . company-quickhelp-mode))
|
||
#+END_SRC
|
||
** Snippets
|
||
Yasnippet adds support for custom snippets
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package yasnippet
|
||
:hook (prog-mode . yas-minor-mode)
|
||
:custom
|
||
(yas-snippet-dirs
|
||
'("~/.emacs.d/snippets"
|
||
"~/.emacs.d/elpa/yasnippet-snippets-0.6/snippets")))
|
||
#+END_SRC
|
||
|
||
** Debugging
|
||
*** Realgud
|
||
[[https://github.com/realgud/realgud][Realgud]] is a modular frontend for many debuggers, right in Emacs.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package realgud
|
||
:commands
|
||
(realgud:gdb
|
||
realgud:lldb
|
||
realgud:node-inspect
|
||
realgud:pdb
|
||
realgud:trepan3k))
|
||
#+END_SRC
|
||
*** RMSbolt
|
||
[[https://github.com/emacsmirror/rmsbolt][RMSbolt]] Shows disassembly in a buffer next to code, highlighting relevant regions.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package rmsbolt
|
||
:commands rmsbolt-mode)
|
||
#+END_SRC
|
||
** Git
|
||
*** Magit
|
||
It's magic git!
|
||
Keybinds [[https://github.com/emacs-evil/evil-magit][here]]
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package magit
|
||
:general
|
||
(jf-git-def
|
||
"b" 'magit-blame-addition
|
||
"B" 'magit-blame-reverse
|
||
"s" 'magit-status))
|
||
#+END_SRC
|
||
It's *evil* magic git!
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package evil-magit
|
||
:after (evil magit))
|
||
#+END_SRC
|
||
*** Forge
|
||
Magic GitHub facilities for git forges such as GitHub and GitLab!
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package forge
|
||
:after magit)
|
||
#+END_SRC
|
||
*** Smeargle
|
||
Highlights regions in files by last update time.
|
||
Older regions are more whitey and newer regions are more blacky.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package smeargle
|
||
:general
|
||
(jf-git-def
|
||
"H t" 'smeargle
|
||
"H h" 'smeargle-commits
|
||
"H c" 'smeargle-clear))
|
||
#+END_SRC
|
||
** Projects
|
||
Projectile provides project-level features like
|
||
make shortcuts and file switching
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package projectile
|
||
:defer t
|
||
:preface
|
||
(defvar jf-projects-path "~/Documents/dev")
|
||
|
||
:general
|
||
(jf-leader-def
|
||
"p" '(:keymap projectile-command-map))
|
||
|
||
:config
|
||
(projectile-mode 1)
|
||
;; Discover projects in jf-projects-path
|
||
(let ((subdirs (directory-files jf-projects-path t)))
|
||
(dolist (dir subdirs)
|
||
(unless (member (file-name-nondirectory dir) '(".." "."))
|
||
(when (file-directory-p dir)
|
||
(let ((default-directory dir)
|
||
(projectile-cached-project-root dir))
|
||
(when (projectile-project-p)
|
||
(projectile-add-known-project (projectile-project-root))))))))
|
||
|
||
:custom
|
||
(projectile-completion-system 'ivy)
|
||
(projectile-project-search-path (list jf-projects-path)))
|
||
#+END_SRC
|
||
** Languages
|
||
*** Fish
|
||
Mode for editing of scripts for the fish shell.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package fish-mode
|
||
:mode "\\.fish\\'")
|
||
#+END_SRC
|
||
*** Markdown
|
||
Mode for editing markdown.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package markdown-mode
|
||
:mode "\\.md\\'")
|
||
#+END_SRC
|
||
|
||
*** Python
|
||
Jedi for autocompletion sources in python-mode.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package company-jedi
|
||
:company python-mode)
|
||
#+END_SRC
|
||
*** Javascript
|
||
[[https://github.com/mooz/js2-mode][js2-mode]] improves the default js mode.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package js2-mode
|
||
:mode "\\.js\\'"
|
||
:interpreter "node")
|
||
#+END_SRC
|
||
*** Web
|
||
Web-mode should give everything you need for a web-dev major mode.
|
||
Company integration is done with company-web.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package web-mode
|
||
:mode ("\\.html\\'"
|
||
"\\.php\\'"
|
||
"\\.blade\\.")
|
||
:custom
|
||
(web-mode-code-indent-offset 4)
|
||
(web-mode-indent-style 4))
|
||
|
||
(use-package company-web
|
||
:company web-mode)
|
||
#+END_SRC
|
||
|
||
*** JSON
|
||
Mode for editing JSON files.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package json-mode
|
||
:mode "\\.json\\'")
|
||
#+END_SRC
|
||
*** YAML
|
||
Mode for editing YAML files.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package yaml-mode
|
||
:mode "\\.yaml\\'")
|
||
#+END_SRC
|
||
|
||
*** Arch PKGBUILD
|
||
Mode for editing PKGBUILD files.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package pkgbuild-mode
|
||
:mode ".*PKGBUILD\\'")
|
||
#+END_SRC
|
||
|
||
*** LaTeX
|
||
**** AUCTeX
|
||
AUCTeX is a major mode for editing TeX.
|
||
Company completions are handled by company-auctex and company-math.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package tex
|
||
:defer t
|
||
:ensure auctex
|
||
:general
|
||
(jf-major-def
|
||
:keymaps 'TeX-mode-map
|
||
"e" 'TeX-command-run-all)
|
||
|
||
:custom
|
||
(TeX-auto-save t))
|
||
|
||
(use-package company-auctex
|
||
:company LaTeX-mode)
|
||
|
||
(use-package company-math
|
||
:company ((TeX-mode . company-math-symbols-latex)
|
||
(TeX-mode . company-math-symbols-unicode)
|
||
(TeX-mode . company-latex-commands)))
|
||
#+END_SRC
|
||
**** Cdlatex
|
||
cdlatex adds better TeX-specific template expansions and other niceties.
|
||
***** Environment
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-cdlatex-envs nil)
|
||
#+END_SRC
|
||
***** Commands
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-cdlatex-commands nil)
|
||
#+END_SRC
|
||
***** Math Symbols
|
||
#+BEGIN_SRC emacs-lisp
|
||
(setq jf-cdlatex-symbols
|
||
'((?I ("\\infty"))))
|
||
#+END_SRC
|
||
***** Setup
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package cdlatex
|
||
:hook (LaTeX-mode . cdlatex-mode)
|
||
:custom
|
||
(cdlatex-env-alist jf-cdlatex-envs)
|
||
(cdlatex-command-alist jf-cdlatex-commands)
|
||
(cdlatex-math-symbol-alist jf-cdlatex-symbols))
|
||
#+END_SRC
|
||
*** Rust
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package rust-mode
|
||
:mode "\\.rs\\'"
|
||
:general)
|
||
|
||
(use-package flycheck-rust
|
||
:after flycheck
|
||
:hook (rust-mode . flycheck-rust-setup))
|
||
|
||
(use-package racer
|
||
:hook ((rust-mode . racer-mode)
|
||
(rust-mode . eldoc-mode))
|
||
:custom
|
||
(racer-cmd "~/.cargo/bin/racer")
|
||
(racer-rust-src-path "~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src"))
|
||
|
||
(use-package cargo
|
||
:hook (rust-mode . cargo-minor-mode)
|
||
:general
|
||
(jf-major-def
|
||
:keymaps 'rust-mode-map
|
||
"b" #'cargo-process-build
|
||
"r" #'cargo-process-run
|
||
"t" #'cargo-process-test))
|
||
#+END_SRC
|
||
*** C/C++
|
||
**** Irony
|
||
Irony handles enhanced C/C++ operations powered by clang
|
||
company-irony for company integration
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package irony
|
||
:hook ((c-mode c++-mode) . irony-mode)
|
||
(irony-mode . irony-cdb-autosetup-compile-options))
|
||
|
||
(use-package flycheck-irony
|
||
:after flycheck
|
||
:hook (irony-mode . flycheck-irony-setup))
|
||
|
||
(use-package company-irony
|
||
:company irony-mode)
|
||
|
||
(use-package company-irony-c-headers
|
||
:company irony-mode)
|
||
#+END_SRC
|
||
*** Lua
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package lua-mode
|
||
:mode "\\.lua\\'")
|
||
|
||
(use-package company-lua
|
||
:company lua-mode)
|
||
#+END_SRC
|