Emacs From Scratch #7 - Configure Everything with Org Babel

- Re-organize emacs config as org document with org babel
- Add evil-easymotion package
This commit is contained in:
Sravan Balaji
2021-04-28 21:04:04 -04:00
parent da6527073a
commit d83759bb5d
2 changed files with 781 additions and 491 deletions

View File

@@ -1,349 +1,548 @@
#+title: Personal Emacs Configuration #+title: Personal Emacs Configuration
#+author: Sravan Balaji #+author: Sravan Balaji
#+PROPERTY: header-args:emacs-lisp :tangle ./init.el
* Sravan Balaji's Emacs Configuration * Sravan Balaji's Emacs Configuration
** Welcome
My personal configuration of Emacs, written as an [[https://orgmode.org][Org Mode]] document. My personal configuration of Emacs, written as an [[https://orgmode.org][Org Mode]] document.
* Configuration Run the block below with `C-c C-c` to tangle code blocks to config file.
** UI Changes #+begin_src emacs-lisp :tangle no
(org-mode-restart)
(org-babel-tangle)
#+end_src
*** Disable Unnecessary Visual Elements ** Configuration Variables
#+begin_src emacs-lisp
(defvar sb/default-font-size 115)
(defvar sb/default-variable-font-size 115)
(defvar sb/modeline-height 15)
#+end_src
* Package System Setup
Package sources and initialization.
#+begin_src emacs-lisp
;; Initialize package sources
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "https://elpa.gnu.org/packages/")))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
;; Initialize use-package on non-Linux platforms
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
#+end_src
* Basic UI Configuration
** Disable Unnecessary Visual Elements
Disable some visual elements that are not necessary like startup message, scrollbar, toolbar, tooltips, menu bar, etc. Disable some visual elements that are not necessary like startup message, scrollbar, toolbar, tooltips, menu bar, etc.
Turn on the visual bell and add some breathing room. Turn on the visual bell and add some breathing room.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(setq inhibit-startup-message t) ; Disable startup message (setq inhibit-startup-message t) ; Disable startup message
(scroll-bar-mode -1) ; Disable visible scrollbar (scroll-bar-mode -1) ; Disable visible scrollbar
(tool-bar-mode -1) ; Disable the toolbar (tool-bar-mode -1) ; Disable the toolbar
(tooltip-mode -1) ; Disable tooltips (tooltip-mode -1) ; Disable tooltips
(set-fringe-mode 10) ; Give some breathing room (set-fringe-mode 10) ; Give some breathing room
(menu-bar-mode -1) ; Disable the menu bar (menu-bar-mode -1) ; Disable the menu bar
(setq visible-bell t) ; Set up the visible bell (setq visible-bell t) ; Set up the visible bell
#+end_src #+end_src
*** Modeline ** Line Numbers
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Doom Modeline ;; Line Numbers
(use-package doom-modeline (column-number-mode)
:ensure t (global-display-line-numbers-mode t)
:init (doom-modeline-mode 1)
:custom (doom-modeline-height 15) ;; Disable line numbers for some modes
) (dolist (mode '(org-mode-hook
term-mode-hook
shell-mode-hook
eshell-mode-hook))
(add-hook mode (lambda () (display-line-numbers-mode 0))))
#+end_src #+end_src
*** Theme ** Font Configuration
Setup FiraCode and Cantarell fonts with specified size.
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; ;; Doom Themes (set-face-attribute 'default nil :font "FiraCode Nerd Font" :height sb/default-font-size)
;; (use-package doom-themes
;; :init (load-theme 'doom-dracula t)
;; )
;; Dracula Pro Theme ;; Set the fixed pitch face
(add-to-list 'custom-theme-load-path "~/.config/emacs/themes") (set-face-attribute 'fixed-pitch nil :font "FiraCode Nerd Font" :height sb/default-font-size)
(load-theme 'dracula-pro t)
;; Set the variable pitch face
(set-face-attribute 'variable-pitch nil :font "Cantarell" :height sb/default-font-size :weight 'regular)
#+end_src #+end_src
*** Line Numbers * Keybindings
** General
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Line Numbers ;; Make ESC quit prompts
(column-number-mode) (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
(global-display-line-numbers-mode t)
;; Disable line numbers for some modes ;; General (for easy keybindings)
(dolist (mode '( (use-package general
org-mode-hook :config
term-mode-hook (general-create-definer sb/leader-keys
shell-mode-hook :keymaps '(normal insert visual emacs)
eshell-mode-hook :prefix "SPC"
) :global-prefix "C-SPC")
)
(add-hook mode (lambda () (display-line-numbers-mode 0)))) (sb/leader-keys
"t" '(:ignore t :which-key "toggles")
"tc" '(comment-line :which-key "toggle comment")
"s" '(:ignore s :which-key "settings")))
(general-define-key
"C-M-j" 'counsel-switch-buffer
)
#+end_src #+end_src
*** Rainbow Delimeters ** Evil Keybindings
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Rainbow Delimiters ;; Evil Keybindings
(use-package rainbow-delimiters (use-package evil
:hook (prog-mode . rainbow-delimiters-mode)) :init
(setq evil-want-integration t)
(setq evil-want-keybinding nil)
(setq evil-want-C-u-scroll t)
(setq evil-want-C-i-jump nil)
:config
(evil-mode 1)
(define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state)
(define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join)
;; Use visual line motions even outside of visual-line-mode buffers
(evil-global-set-key 'motion "j" 'evil-next-visual-line)
(evil-global-set-key 'motion "k" 'evil-previous-visual-line)
(evil-set-initial-state 'messages-buffer-mode 'normal)
(evil-set-initial-state 'dashboard-mode 'normal)
)
(use-package evil-collection
:after evil
:config
(evil-collection-init)
)
;; Easymotion
(use-package evil-easymotion
:config
(evilem-default-keybindings "SPC"))
#+end_src #+end_src
** Fonts * UI Configuration
Setup FiraCode font with specified size. ** Color Theme
NOTE: The first time you load your configuration on a new machine, you'll #+begin_src emacs-lisp
;; ;; Dracula Doom Theme
;; (use-package doom-themes
;; :init (load-theme 'doom-dracula t))
;; Dracula Pro Theme
(add-to-list 'custom-theme-load-path "~/.config/emacs/themes")
(load-theme 'dracula-pro t)
#+end_src
** Better Modeline
*NOTE*: The first time you load your configuration on a new machine, you'll
need to run the following command interactively so that mode line icons need to run the following command interactively so that mode line icons
display correctly: display correctly:
M-X all-the-icons-install-fonts `M-x all-the-icons-install-fonts`
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Font setup ;; Icon Fonts
(set-face-attribute 'default nil :font "FiraCode Nerd Font" :height 120) (use-package all-the-icons)
;; Icon Fonts ;; Doom Modeline
(use-package all-the-icons) (use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1)
:custom ((doom-modeline-height sb/modeline-height)))
#+end_src #+end_src
** Keybindings ** Which Key
Evil mode keybindings.
*** General
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Make ESC quit prompts (use-package which-key
(global-set-key (kbd "<escape>") 'keyboard-escape-quit) :init (which-key-mode)
:diminish which-key-mode
:config
(setq which-key-idle-delay 1))
#+end_src
;; General (for easy keybindings) ** Ivy and Counsel
(use-package general
:config #+begin_src emacs-lisp
(general-create-definer sb/leader-keys ;; Ivy Autocompletion
:keymaps '(normal insert visual emacs) (use-package ivy
:prefix "SPC" :diminish
:global-prefix "C-SPC") :bind (("C-s" . swiper)
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
("C-j" . ivy-next-line)
("C-k" . ivy-previous-line)
:map ivy-switch-buffer-map
("C-k" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-k" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode 1))
;; Ivy Rich
(use-package ivy-rich
:init
(ivy-rich-mode 1))
;; Counsel
(use-package counsel
:bind (("C-M-j" . 'counsel-switch-buffer)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history))
:config
(counsel-mode 1))
(sb/leader-keys (sb/leader-keys
"t" '(:ignore t :which-key "toggles") "st" '(counsel-load-theme :which-key "choose theme"))
"tc" '(comment-line :which-key "toggle comment")
"s" '(:ignore s :which-key "settings")
"st" '(counsel-load-theme :which-key "choose theme")
"ss" '(hydra-text-scale/body :which-key "scale text")
)
)
(general-define-key
"C-M-j" 'counsel-switch-buffer
)
#+end_src #+end_src
*** Evil Keybindings ** Helpful Help Commands
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Evil Keybindings ;; Helpful
(use-package evil (use-package helpful
:init :custom
(setq evil-want-integration t) (counsel-describe-function-function #'helpful-callable)
(setq evil-want-keybinding nil) (counsel-describe-variable-function #'helpful-variable)
(setq evil-want-C-u-scroll t) :bind
(setq evil-want-C-i-jump nil) ([remap describe-function] . counsel-describe-function)
:config ([remap describe-command] . helpful-command)
(evil-mode 1) ([remap describe-variable] . counsel-describe-variable)
(define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state) ([remap describe-key] . helpful-key))
(define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join)
;; Use visual line motoins even outside of visual-line-mode buffers
(evil-global-set-key 'motion "j" 'evil-next-visual-line)
(evil-global-set-key 'motion "k" 'evil-previous-visual-line)
(evil-set-initial-state 'messages-buffer-mode 'normal)
(evil-set-initial-state 'dashboard-mode 'normal)
)
(use-package evil-collection
:after evil
:config
(evil-collection-init)
)
#+end_src #+end_src
*** Hydra ** Text Scaling
Use Hydra to design a transient key binding for quickly adjusting the scale of the text on screen.
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Hydra ;; Hydra
(use-package hydra) (use-package hydra)
(defhydra hydra-text-scale (:timeout 4) (defhydra hydra-text-scale (:timeout 4)
"scale text" "scale text"
("j" text-scale-increase "in") ("j" text-scale-increase "in")
("k" text-scale-decrease "out") ("k" text-scale-decrease "out")
("f" nil "finished" :exit t) ("f" nil "finished" :exit t)
)
#+end_src
** Package Sources
Package sources and initialization.
#+begin_src emacs-lisp
;; Initialize package sources
(require 'package)
(setq package-archives
'(("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "https://elpa.gnu.org/packages/")
)
)
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
;; Initialize use-package on non-Linux platforms
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
#+end_src
** Autocompletion
#+begin_src emacs-lisp
;; Ivy Autocompletion
(use-package ivy
:diminish
:bind (("C-s" . swiper)
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
("C-j" . ivy-next-line)
("C-k" . ivy-previous-line)
:map ivy-switch-buffer-map
("C-k" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-k" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode 1)
) )
;; Ivy Rich (sb/leader-keys
(use-package ivy-rich "ss" '(hydra-text-scale/body :which-key "scale text"))
:init
(ivy-rich-mode 1))
;; Counsel
(use-package counsel
:bind (("M-x" . counsel-M-x)
("C-x b" . counsel-ibuffer)
("C-x C-f" . counsel-find-file)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history)))
;; Helpful
(use-package helpful
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable)
:bind
([remap describe-function] . counsel-describe-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . counsel-describe-variable)
([remap describe-key] . helpful-key))
#+end_src #+end_src
* Org Mode
** Better Font Faces
#+begin_src emacs-lisp
(defun sb/org-font-setup ()
;; Replace list hyphen with dot
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))
;; Set faces for heading levels
(dolist (face '((org-level-1 . 1.2)
(org-level-2 . 1.1)
(org-level-3 . 1.05)
(org-level-4 . 1.0)
(org-level-5 . 1.1)
(org-level-6 . 1.1)
(org-level-7 . 1.1)
(org-level-8 . 1.1)))
(set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face)))
;; Ensure that anything that should be fixed-pitch in Org files appears that way
(set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch))
#+end_src
** Basic Config
#+begin_src emacs-lisp
(defun sb/org-mode-setup ()
(org-indent-mode)
(variable-pitch-mode 1)
(visual-line-mode 1))
(use-package org
:hook (org-mode . sb/org-mode-setup)
:config
(setq org-ellipsis "")
(setq org-agenda-start-with-log-mode t)
(setq org-log-done 'time)
(setq org-log-into-drawer t)
(setq org-agenda-files
'("~/Projects/Code/emacs-from-scratch/OrgFiles/Tasks.org"
"~/Projects/Code/emacs-from-scratch/OrgFiles/Habits.org"
"~/Projects/Code/emacs-from-scratch/OrgFiles/Birthdays.org"))
(require 'org-habit)
(add-to-list 'org-modules 'org-habit)
(setq org-habit-graph-column 60)
(setq org-todo-keywords
'((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
(sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANC(k@)")))
(setq org-refile-targets
'(("Archive.org" :maxlevel . 1)
("Tasks.org" :maxlevel . 1)))
;; Save Org buffers after refiling!
(advice-add 'org-refile :after 'org-save-all-org-buffers)
(setq org-tag-alist
'((:startgroup)
; Put mutually exclusive tags here
(:endgroup)
("@errand" . ?E)
("@home" . ?H)
("@work" . ?W)
("agenda" . ?a)
("planning" . ?p)
("publish" . ?P)
("batch" . ?b)
("note" . ?n)
("idea" . ?i)))
;; Configure custom agenda views
(setq org-agenda-custom-commands
'(("d" "Dashboard"
((agenda "" ((org-deadline-warning-days 7)))
(todo "NEXT"
((org-agenda-overriding-header "Next Tasks")))
(tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))
("n" "Next Tasks"
((todo "NEXT"
((org-agenda-overriding-header "Next Tasks")))))
("W" "Work Tasks" tags-todo "+work-email")
;; Low-effort next actions
("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
((org-agenda-overriding-header "Low Effort Tasks")
(org-agenda-max-todos 20)
(org-agenda-files org-agenda-files)))
("w" "Workflow Status"
((todo "WAIT"
((org-agenda-overriding-header "Waiting on External")
(org-agenda-files org-agenda-files)))
(todo "REVIEW"
((org-agenda-overriding-header "In Review")
(org-agenda-files org-agenda-files)))
(todo "PLAN"
((org-agenda-overriding-header "In Planning")
(org-agenda-todo-list-sublevels nil)
(org-agenda-files org-agenda-files)))
(todo "BACKLOG"
((org-agenda-overriding-header "Project Backlog")
(org-agenda-todo-list-sublevels nil)
(org-agenda-files org-agenda-files)))
(todo "READY"
((org-agenda-overriding-header "Ready for Work")
(org-agenda-files org-agenda-files)))
(todo "ACTIVE"
((org-agenda-overriding-header "Active Projects")
(org-agenda-files org-agenda-files)))
(todo "COMPLETED"
((org-agenda-overriding-header "Completed Projects")
(org-agenda-files org-agenda-files)))
(todo "CANC"
((org-agenda-overriding-header "Cancelled Projects")
(org-agenda-files org-agenda-files)))))))
(setq org-capture-templates
`(("t" "Tasks / Projects")
("tt" "Task" entry (file+olp "~/Projects/Code/emacs-from-scratch/OrgFiles/Tasks.org" "Inbox")
"* TODO %?\n %U\n %a\n %i" :empty-lines 1)
("j" "Journal Entries")
("jj" "Journal" entry
(file+olp+datetree "~/Projects/Code/emacs-from-scratch/OrgFiles/Journal.org")
"\n* %<%I:%M %p> - Journal :journal:\n\n%?\n\n"
;; ,(dw/read-file-as-string "~/Notes/Templates/Daily.org")
:clock-in :clock-resume
:empty-lines 1)
("jm" "Meeting" entry
(file+olp+datetree "~/Projects/Code/emacs-from-scratch/OrgFiles/Journal.org")
"* %<%I:%M %p> - %a :meetings:\n\n%?\n\n"
:clock-in :clock-resume
:empty-lines 1)
("w" "Workflows")
("we" "Checking Email" entry (file+olp+datetree "~/Projects/Code/emacs-from-scratch/OrgFiles/Journal.org")
"* Checking Email :email:\n\n%?" :clock-in :clock-resume :empty-lines 1)
("m" "Metrics Capture")
("mw" "Weight" table-line (file+headline "~/Projects/Code/emacs-from-scratch/OrgFiles/Metrics.org" "Weight")
"| %U | %^{Weight} | %^{Notes} |" :kill-buffer t)))
(define-key global-map (kbd "C-c j")
(lambda () (interactive) (org-capture nil "jj")))
(sb/org-font-setup))
#+end_src
*** Nicer Heading Bullets
#+begin_src emacs-lisp
(use-package org-bullets
:after org
:hook (org-mode . org-bullets-mode)
:custom
(org-bullets-bullet-list '("" "" "" "" "" "" "")))
#+end_src
*** Center Org Buffers
#+begin_src emacs-lisp
(defun sb/org-mode-visual-fill ()
(setq visual-fill-column-width 100
visual-fill-column-center-text t)
(visual-fill-column-mode 1))
(use-package visual-fill-column
:hook (org-mode . sb/org-mode-visual-fill))
#+end_src
** Configure Babel Languages
#+begin_src emacs-lisp
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(python . t)))
(push '("conf-unix" . conf-unix) org-src-lang-modes)
#+end_src
** Structure Templates
#+begin_src emacs-lisp
;; This is needed as of Org 9.2
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
#+end_src
** Auto-Tangle Configuration Files
Automatically tangle code blocks in file everytime it is saved.
#+begin_src emacs-lisp
;; Automatically tangle our Emacs.org config file when we save it
(defun sb/org-babel-tangle-config ()
(when (string-equal (buffer-file-name)
(expand-file-name "~/.config/emacs/README.org"))
;; Dynamic scoping to the rescue
(let ((org-confirm-babel-evaluate nil))
(org-babel-tangle))))
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'sb/org-babel-tangle-config)))
#+end_src
* Development
** Projectile ** Projectile
#+begin_src emacs-lisp
;; Projectile
(use-package projectile
:diminish projectile-mode
:config (projectile-mode)
:custom ((projectile-completion-system 'ivy))
:bind-keymap
("C-c p" . projectile-command-map)
:init
(when (file-directory-p "~/Projects")
(setq projectile-project-search-path '("~/Projects/Personal" "~/Projects/UMICH")))
(when (file-directory-p "~/.config")
(setq projectile-project-search-path '("~/.config")))
(setq projectile-switch-project-action #'projectile-dired))
(use-package counsel-projectile
:config (counsel-projectile-mode))
#+end_src
** Magit
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Projectile ;; Magit
(use-package projectile (use-package magit
:diminish projectile-mode :custom
:config (projectile-mode) (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
:custom ((projectile-completion-system 'ivy))
:bind-keymap
("C-c p" . projectile-command-map)
:init
(when (file-directory-p "~/Projects")
(setq projectile-project-search-path '("~/Projects/Personal" "~/Projects/UMICH"))
) )
(when (file-directory-p "~/.config")
(setq projectile-project-search-path '("~/.config"))
)
(setq projectile-switch-project-action #'projectile-dired)
)
(use-package counsel-projectile ;; NOTE: evil-magit was removed from MELPA and now a part of evil-collection
:config (counsel-projectile-mode) ;; (use-package evil-magit
) ;; :after magit
;; )
;; ;; NOTE: Make sure to configure a GitHub token before using this package!
;; ;; - https://magit.vc/manual/forge/Token-Creation.html#Token-Creation
;; ;; - https://magit.vc/manual/ghub/Getting-Started.html#Getting-Started
;; (use-package forge)
#+end_src #+end_src
** Git Integration ** Rainbow Delimeters
*** Magit
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; Magit ;; Rainbow Delimiters
(use-package magit (use-package rainbow-delimiters
;; :commands (magit-status magit-get-current-branch) :hook (prog-mode . rainbow-delimiters-mode))
:custom
(magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
)
;; NOTE: evil-magit was removed from MELPA and now a part of evil-collection
;; (use-package evil-magit
;; :after magit
;; )
#+end_src #+end_src
*** Forge
#+begin_src emacs-lisp
;; OPTIONAL: This will add GitHub integration to magit, but requires some token setup
;; (use-package forge)
#+end_src
** Org Mode
#+begin_src emacs-lisp
(defun sb/org-mode-setup ()
(org-indent-mode)
;; (variable-pitch-mode 1)
(auto-fill-mode 0)
(visual-line-mode 1)
(setq evil-auto-indent nil)
)
;; Replace list hyphen with dot
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))
;; ;; Set faces for heading levels
;; (dolist (face '((org-level-1 . 1.2)
;; (org-level-2 . 1.1)
;; (org-level-3 . 1.05)
;; (org-level-4 . 1.0)
;; (org-level-5 . 1.1)
;; (org-level-6 . 1.1)
;; (org-level-7 . 1.1)
;; (org-level-8 . 1.1)))
;; (set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face)))
(use-package org
:hook (org-mode . sb/org-mode-setup)
:config
(setq org-ellipsis "")
(sb/org-font-setup)
)
(use-package org-bullets
:after org
:hook (org-mode . org-bullets-mode)
:custom
(org-bullets-bullet-list '("" "" "" "" "" "" ""))
)
;; ;; Add visual fill (padding)
;; (defun sb/org-mode-visual-fill ()
;; (setq visual-fill-column-width 100
;; visual-fill-column-center-text t)
;; (visual-fill-column-mode 1)
;; )
;; (use-package visual-fill-column
;; :hook (org-mode . sb/org-mode-visual-fill)
;; )
#+end_src

525
init.el
View File

@@ -1,29 +1,13 @@
(setq inhibit-startup-message t) ; Disable startup message (defvar sb/default-font-size 115)
(defvar sb/default-variable-font-size 115)
(scroll-bar-mode -1) ; Disable visible scrollbar (defvar sb/modeline-height 15)
(tool-bar-mode -1) ; Disable the toolbar
(tooltip-mode -1) ; Disable tooltips
(set-fringe-mode 10) ; Give some breathing room
(menu-bar-mode -1) ; Disable the menu bar
(setq visible-bell t) ; Set up the visible bell
;; Font setup
(set-face-attribute 'default nil :font "FiraCode Nerd Font" :height 120)
;; Make ESC quit prompts
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
;; Initialize package sources ;; Initialize package sources
(require 'package) (require 'package)
(setq package-archives (setq package-archives '(("melpa" . "https://melpa.org/packages/")
'(("melpa" . "https://melpa.org/packages/") ("org" . "https://orgmode.org/elpa/")
("org" . "https://orgmode.org/elpa/") ("elpa" . "https://elpa.gnu.org/packages/")))
("elpa" . "https://elpa.gnu.org/packages/")
)
)
(package-initialize) (package-initialize)
(unless package-archive-contents (unless package-archive-contents
@@ -36,147 +20,38 @@
(require 'use-package) (require 'use-package)
(setq use-package-always-ensure t) (setq use-package-always-ensure t)
; (use-package command-log-mode) (setq inhibit-startup-message t) ; Disable startup message
; Ivy Autocompletion (scroll-bar-mode -1) ; Disable visible scrollbar
(use-package ivy (tool-bar-mode -1) ; Disable the toolbar
:diminish (tooltip-mode -1) ; Disable tooltips
:bind (("C-s" . swiper) (set-fringe-mode 10) ; Give some breathing room
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
("C-j" . ivy-next-line)
("C-k" . ivy-previous-line)
:map ivy-switch-buffer-map
("C-k" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-k" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode 1)
)
;; Doom Modeline (menu-bar-mode -1) ; Disable the menu bar
(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1)
:custom (doom-modeline-height 15)
)
;; ;; Doom Themes (setq visible-bell t) ; Set up the visible bell
;; (use-package doom-themes
;; :init (load-theme 'doom-dracula t)
;; )
;; Dracula Pro Theme
(add-to-list 'custom-theme-load-path "~/.config/emacs/themes")
(load-theme 'dracula-pro t)
;; NOTE: The first time you load your configuration on a new machine, you'll
;; need to run the following command interactively so that mode line icons
;; display correctly:
;;
;; M-X all-the-icons-install-fonts
(use-package all-the-icons)
(custom-set-variables
;; custom-set-variables 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.
'(ansi-color-names-vector
["#282a36" "#ff5555" "#50fa7b" "#f1fa8c" "#61bfff" "#ff79c6" "#8be9fd" "#f8f8f2"])
'(custom-safe-themes
'("64811e7fdbf77f278cf304e27f901f1095cc0090b5c032b0a9759c4df3fa82cc" "e6ff132edb1bfa0645e2ba032c44ce94a3bd3c15e3929cdf6c049802cf059a2a" "e5c595b20563da64003b24f655310089a14e5741c681c5072f24a4f376b8e2ce" default))
'(fci-rule-color "#6272a4")
'(jdee-db-active-breakpoint-face-colors (cons "#1E2029" "#bd93f9"))
'(jdee-db-requested-breakpoint-face-colors (cons "#1E2029" "#50fa7b"))
'(jdee-db-spec-breakpoint-face-colors (cons "#1E2029" "#565761"))
'(objed-cursor-color "#ff5555")
'(package-selected-packages
'(visual-fill-column org-bullets autothemer forge evil-magit magit counsel-projectile projectile hydra evil-collection evil general helpful counsel ivy-rich which-key rainbow-delimiters doom-modeline use-package ivy command-log-mode))
'(pdf-view-midnight-colors (cons "#f8f8f2" "#282a36"))
'(rustic-ansi-faces
["#282a36" "#ff5555" "#50fa7b" "#f1fa8c" "#61bfff" "#ff79c6" "#8be9fd" "#f8f8f2"])
'(vc-annotate-background "#282a36")
'(vc-annotate-color-map
(list
(cons 20 "#50fa7b")
(cons 40 "#85fa80")
(cons 60 "#bbf986")
(cons 80 "#f1fa8c")
(cons 100 "#f5e381")
(cons 120 "#face76")
(cons 140 "#ffb86c")
(cons 160 "#ffa38a")
(cons 180 "#ff8ea8")
(cons 200 "#ff79c6")
(cons 220 "#ff6da0")
(cons 240 "#ff617a")
(cons 260 "#ff5555")
(cons 280 "#d45558")
(cons 300 "#aa565a")
(cons 320 "#80565d")
(cons 340 "#6272a4")
(cons 360 "#6272a4")))
'(vc-annotate-very-old-color nil))
(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.
)
;; Line Numbers ;; Line Numbers
(column-number-mode) (column-number-mode)
(global-display-line-numbers-mode t) (global-display-line-numbers-mode t)
;; Disable line numbers for some modes ;; Disable line numbers for some modes
(dolist (mode '( (dolist (mode '(org-mode-hook
org-mode-hook term-mode-hook
term-mode-hook shell-mode-hook
shell-mode-hook eshell-mode-hook))
eshell-mode-hook (add-hook mode (lambda () (display-line-numbers-mode 0))))
)
)
(add-hook mode (lambda () (display-line-numbers-mode 0))))
;; Rainbow Delimiters (set-face-attribute 'default nil :font "FiraCode Nerd Font" :height sb/default-font-size)
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
;; Which Key ;; Set the fixed pitch face
(use-package which-key (set-face-attribute 'fixed-pitch nil :font "FiraCode Nerd Font" :height sb/default-font-size)
:init (which-key-mode)
:diminish which-key-mode
:config
(setq which-key-idle-delay 0.1)
)
;; Ivy Rich ;; Set the variable pitch face
(use-package ivy-rich (set-face-attribute 'variable-pitch nil :font "Cantarell" :height sb/default-font-size :weight 'regular)
:init
(ivy-rich-mode 1))
;; Counsel ;; Make ESC quit prompts
(use-package counsel (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
:bind (("M-x" . counsel-M-x)
("C-x b" . counsel-ibuffer)
("C-x C-f" . counsel-find-file)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history)))
;; Helpful
(use-package helpful
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable)
:bind
([remap describe-function] . counsel-describe-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . counsel-describe-variable)
([remap describe-key] . helpful-key))
;; General (for easy keybindings) ;; General (for easy keybindings)
(use-package general (use-package general
@@ -189,12 +64,8 @@
(sb/leader-keys (sb/leader-keys
"t" '(:ignore t :which-key "toggles") "t" '(:ignore t :which-key "toggles")
"tc" '(comment-line :which-key "toggle comment") "tc" '(comment-line :which-key "toggle comment")
"s" '(:ignore s :which-key "settings") "s" '(:ignore s :which-key "settings")))
"st" '(counsel-load-theme :which-key "choose theme")
"ss" '(hydra-text-scale/body :which-key "scale text")
)
)
(general-define-key (general-define-key
"C-M-j" 'counsel-switch-buffer "C-M-j" 'counsel-switch-buffer
) )
@@ -211,10 +82,10 @@
(define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state) (define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state)
(define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join) (define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join)
;; Use visual line motoins even outside of visual-line-mode buffers ;; Use visual line motions even outside of visual-line-mode buffers
(evil-global-set-key 'motion "j" 'evil-next-visual-line) (evil-global-set-key 'motion "j" 'evil-next-visual-line)
(evil-global-set-key 'motion "k" 'evil-previous-visual-line) (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
(evil-set-initial-state 'messages-buffer-mode 'normal) (evil-set-initial-state 'messages-buffer-mode 'normal)
(evil-set-initial-state 'dashboard-mode 'normal) (evil-set-initial-state 'dashboard-mode 'normal)
) )
@@ -225,6 +96,80 @@
(evil-collection-init) (evil-collection-init)
) )
;; Easymotion
(use-package evil-easymotion
:config
(evilem-default-keybindings "SPC"))
;; ;; Dracula Doom Theme
;; (use-package doom-themes
;; :init (load-theme 'doom-dracula t))
;; Dracula Pro Theme
(add-to-list 'custom-theme-load-path "~/.config/emacs/themes")
(load-theme 'dracula-pro t)
;; Icon Fonts
(use-package all-the-icons)
;; Doom Modeline
(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1)
:custom ((doom-modeline-height sb/modeline-height)))
(use-package which-key
:init (which-key-mode)
:diminish which-key-mode
:config
(setq which-key-idle-delay 1))
;; Ivy Autocompletion
(use-package ivy
:diminish
:bind (("C-s" . swiper)
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
("C-j" . ivy-next-line)
("C-k" . ivy-previous-line)
:map ivy-switch-buffer-map
("C-k" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-k" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode 1))
;; Ivy Rich
(use-package ivy-rich
:init
(ivy-rich-mode 1))
;; Counsel
(use-package counsel
:bind (("C-M-j" . 'counsel-switch-buffer)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history))
:config
(counsel-mode 1))
(sb/leader-keys
"st" '(counsel-load-theme :which-key "choose theme"))
;; Helpful
(use-package helpful
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable)
:bind
([remap describe-function] . counsel-describe-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . counsel-describe-variable)
([remap describe-key] . helpful-key))
;; Hydra ;; Hydra
(use-package hydra) (use-package hydra)
@@ -235,6 +180,200 @@
("f" nil "finished" :exit t) ("f" nil "finished" :exit t)
) )
(sb/leader-keys
"ss" '(hydra-text-scale/body :which-key "scale text"))
(defun sb/org-font-setup ()
;; Replace list hyphen with dot
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))
;; Set faces for heading levels
(dolist (face '((org-level-1 . 1.2)
(org-level-2 . 1.1)
(org-level-3 . 1.05)
(org-level-4 . 1.0)
(org-level-5 . 1.1)
(org-level-6 . 1.1)
(org-level-7 . 1.1)
(org-level-8 . 1.1)))
(set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face)))
;; Ensure that anything that should be fixed-pitch in Org files appears that way
(set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch))
(defun sb/org-mode-setup ()
(org-indent-mode)
(variable-pitch-mode 1)
(visual-line-mode 1))
(use-package org
:hook (org-mode . sb/org-mode-setup)
:config
(setq org-ellipsis "")
(setq org-agenda-start-with-log-mode t)
(setq org-log-done 'time)
(setq org-log-into-drawer t)
(setq org-agenda-files
'("~/Projects/Code/emacs-from-scratch/OrgFiles/Tasks.org"
"~/Projects/Code/emacs-from-scratch/OrgFiles/Habits.org"
"~/Projects/Code/emacs-from-scratch/OrgFiles/Birthdays.org"))
(require 'org-habit)
(add-to-list 'org-modules 'org-habit)
(setq org-habit-graph-column 60)
(setq org-todo-keywords
'((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
(sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANC(k@)")))
(setq org-refile-targets
'(("Archive.org" :maxlevel . 1)
("Tasks.org" :maxlevel . 1)))
;; Save Org buffers after refiling!
(advice-add 'org-refile :after 'org-save-all-org-buffers)
(setq org-tag-alist
'((:startgroup)
; Put mutually exclusive tags here
(:endgroup)
("@errand" . ?E)
("@home" . ?H)
("@work" . ?W)
("agenda" . ?a)
("planning" . ?p)
("publish" . ?P)
("batch" . ?b)
("note" . ?n)
("idea" . ?i)))
;; Configure custom agenda views
(setq org-agenda-custom-commands
'(("d" "Dashboard"
((agenda "" ((org-deadline-warning-days 7)))
(todo "NEXT"
((org-agenda-overriding-header "Next Tasks")))
(tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))
("n" "Next Tasks"
((todo "NEXT"
((org-agenda-overriding-header "Next Tasks")))))
("W" "Work Tasks" tags-todo "+work-email")
;; Low-effort next actions
("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
((org-agenda-overriding-header "Low Effort Tasks")
(org-agenda-max-todos 20)
(org-agenda-files org-agenda-files)))
("w" "Workflow Status"
((todo "WAIT"
((org-agenda-overriding-header "Waiting on External")
(org-agenda-files org-agenda-files)))
(todo "REVIEW"
((org-agenda-overriding-header "In Review")
(org-agenda-files org-agenda-files)))
(todo "PLAN"
((org-agenda-overriding-header "In Planning")
(org-agenda-todo-list-sublevels nil)
(org-agenda-files org-agenda-files)))
(todo "BACKLOG"
((org-agenda-overriding-header "Project Backlog")
(org-agenda-todo-list-sublevels nil)
(org-agenda-files org-agenda-files)))
(todo "READY"
((org-agenda-overriding-header "Ready for Work")
(org-agenda-files org-agenda-files)))
(todo "ACTIVE"
((org-agenda-overriding-header "Active Projects")
(org-agenda-files org-agenda-files)))
(todo "COMPLETED"
((org-agenda-overriding-header "Completed Projects")
(org-agenda-files org-agenda-files)))
(todo "CANC"
((org-agenda-overriding-header "Cancelled Projects")
(org-agenda-files org-agenda-files)))))))
(setq org-capture-templates
`(("t" "Tasks / Projects")
("tt" "Task" entry (file+olp "~/Projects/Code/emacs-from-scratch/OrgFiles/Tasks.org" "Inbox")
"* TODO %?\n %U\n %a\n %i" :empty-lines 1)
("j" "Journal Entries")
("jj" "Journal" entry
(file+olp+datetree "~/Projects/Code/emacs-from-scratch/OrgFiles/Journal.org")
"\n* %<%I:%M %p> - Journal :journal:\n\n%?\n\n"
;; ,(dw/read-file-as-string "~/Notes/Templates/Daily.org")
:clock-in :clock-resume
:empty-lines 1)
("jm" "Meeting" entry
(file+olp+datetree "~/Projects/Code/emacs-from-scratch/OrgFiles/Journal.org")
"* %<%I:%M %p> - %a :meetings:\n\n%?\n\n"
:clock-in :clock-resume
:empty-lines 1)
("w" "Workflows")
("we" "Checking Email" entry (file+olp+datetree "~/Projects/Code/emacs-from-scratch/OrgFiles/Journal.org")
"* Checking Email :email:\n\n%?" :clock-in :clock-resume :empty-lines 1)
("m" "Metrics Capture")
("mw" "Weight" table-line (file+headline "~/Projects/Code/emacs-from-scratch/OrgFiles/Metrics.org" "Weight")
"| %U | %^{Weight} | %^{Notes} |" :kill-buffer t)))
(define-key global-map (kbd "C-c j")
(lambda () (interactive) (org-capture nil "jj")))
(sb/org-font-setup))
(use-package org-bullets
:after org
:hook (org-mode . org-bullets-mode)
:custom
(org-bullets-bullet-list '("" "" "" "" "" "" "")))
(defun sb/org-mode-visual-fill ()
(setq visual-fill-column-width 100
visual-fill-column-center-text t)
(visual-fill-column-mode 1))
(use-package visual-fill-column
:hook (org-mode . sb/org-mode-visual-fill))
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(python . t)))
(push '("conf-unix" . conf-unix) org-src-lang-modes)
;; This is needed as of Org 9.2
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
;; Automatically tangle our Emacs.org config file when we save it
(defun sb/org-babel-tangle-config ()
(when (string-equal (buffer-file-name)
(expand-file-name "~/.config/emacs/README.org"))
;; Dynamic scoping to the rescue
(let ((org-confirm-babel-evaluate nil))
(org-babel-tangle))))
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'sb/org-babel-tangle-config)))
;; Projectile ;; Projectile
(use-package projectile (use-package projectile
:diminish projectile-mode :diminish projectile-mode
@@ -244,21 +383,16 @@
("C-c p" . projectile-command-map) ("C-c p" . projectile-command-map)
:init :init
(when (file-directory-p "~/Projects") (when (file-directory-p "~/Projects")
(setq projectile-project-search-path '("~/Projects/Personal" "~/Projects/UMICH")) (setq projectile-project-search-path '("~/Projects/Personal" "~/Projects/UMICH")))
)
(when (file-directory-p "~/.config") (when (file-directory-p "~/.config")
(setq projectile-project-search-path '("~/.config")) (setq projectile-project-search-path '("~/.config")))
) (setq projectile-switch-project-action #'projectile-dired))
(setq projectile-switch-project-action #'projectile-dired)
)
(use-package counsel-projectile (use-package counsel-projectile
:config (counsel-projectile-mode) :config (counsel-projectile-mode))
)
;; Magit ;; Magit
(use-package magit (use-package magit
;; :commands (magit-status magit-get-current-branch)
:custom :custom
(magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1) (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
) )
@@ -268,54 +402,11 @@
;; :after magit ;; :after magit
;; ) ;; )
;; OPTIONAL: This will add GitHub integration to magit, but requires some token setup ;; ;; NOTE: Make sure to configure a GitHub token before using this package!
;; ;; - https://magit.vc/manual/forge/Token-Creation.html#Token-Creation
;; ;; - https://magit.vc/manual/ghub/Getting-Started.html#Getting-Started
;; (use-package forge) ;; (use-package forge)
(defun sb/org-mode-setup () ;; Rainbow Delimiters
(org-indent-mode) (use-package rainbow-delimiters
;; (variable-pitch-mode 1) :hook (prog-mode . rainbow-delimiters-mode))
(auto-fill-mode 0)
(visual-line-mode 1)
(setq evil-auto-indent nil)
)
;; Replace list hyphen with dot
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))
;; ;; Set faces for heading levels
;; (dolist (face '((org-level-1 . 1.2)
;; (org-level-2 . 1.1)
;; (org-level-3 . 1.05)
;; (org-level-4 . 1.0)
;; (org-level-5 . 1.1)
;; (org-level-6 . 1.1)
;; (org-level-7 . 1.1)
;; (org-level-8 . 1.1)))
;; (set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face)))
(use-package org
:hook (org-mode . sb/org-mode-setup)
:config
(setq org-ellipsis "")
(sb/org-font-setup)
)
(use-package org-bullets
:after org
:hook (org-mode . org-bullets-mode)
:custom
(org-bullets-bullet-list '("" "" "" "" "" "" ""))
)
;; ;; Add visual fill (padding)
;; (defun sb/org-mode-visual-fill ()
;; (setq visual-fill-column-width 100
;; visual-fill-column-center-text t)
;; (visual-fill-column-mode 1)
;; )
;; (use-package visual-fill-column
;; :hook (org-mode . sb/org-mode-visual-fill)
;; )