+TITLE: Emacs Configuration
See .init.el
.init.el set up the magic that is use-package and org-babel-load-file to
allow for confirguration to be literate.
Configure use-package
Use use-package to install and configure packages. My init.el includes
the initial setup for package.el and ensures that use-package is installed.
This makes sure that use-package will install the package if it’s not already
available.
(require 'use-package-ensure)
(setq use-package-always-ensure t)I use this on windows as well and things are just flakier over there so there I am going to turn off package signature check
(if (string-equal system-type "windows-nt")
(setq package-check-signature nil))Always compile packages, and use the newest version available.
(use-package auto-compile
:config (auto-compile-on-load-mode))
(setq load-prefer-newer t)Personal Details Setup
Sets up some personal information sucha as email
(setq user-full-name "Donald Brady" user-mail-address "donald.brady@gmail.com")
Set up savefile, backup, and autosave directories
(defconst dbrady-savefile-dir (expand-file-name "savefile" user-emacs-directory))
;; create the savefile dir if it doesn't exist
(unless (file-exists-p dbrady-savefile-dir) (make-directory dbrady-savefile-dir))
;; store all backup and autosave files in the tmp dir
(setq backup-directory-alist `((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))
;; saveplace remembers your location in a file when saving files
(use-package saveplace
:config
(setq save-place-file (expand-file-name "saveplace" dbrady-savefile-dir))
;; activate it for all buffers
(setq-default save-place t))
(use-package savehist
:config
(setq savehist-additional-variables
;; search entries
'(search-ring regexp-search-ring)
;; save every minute
savehist-autosave-interval 60
;; keep the home clean
savehist-file (expand-file-name "savehist" dbrady-savefile-dir))
(savehist-mode +1))
Basic Configurations
Place for a grab bag of basic settings
(setq inhibit-startup-screen t)
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(setq ring-bell-function 'ignore)
(line-number-mode t)
(column-number-mode t)
(size-indication-mode t)
(fset 'yes-or-no-p 'y-or-n-p)
(setq require-final-newline t)
(setq-default fill-column 80)
(add-hook 'text-mode-hook 'auto-fill-mode)
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
;; smart tab behavior - indent or complete
(setq tab-always-indent 'complete)
(global-display-line-numbers-mode 0) ; line number in margin
(global-hl-line-mode 0) ; highlight current line
(global-auto-revert-mode 1)
;; scroll to the bottom of repls on output
(add-hook 'comint-output-filter-functions 'comint-postoutput-scroll-to-bottom)
(defvar default-gc-cons-threshold most-positive-fixnum
"for startup make hella big during startup.")
;; make garbage collector less invasive
(setq gc-cons-threshold default-gc-cons-threshold gc-cons-percentage 0.6)
;; ediff in same window
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
Custom Packages
Packages here don’t have any major configuration and are loaded vanilla.
(defvar my-packages '(
eglot
elec-pair
flycheck
git-timemachine
gnuplot
s ; some nice easy string manipulation functions
))Loop over the above list, loading using use-package
(dolist (p my-packages)
(unless (package-installed-p p)
(package-refresh-contents)
(package-install p))
(add-to-list 'package-selected-packages p))Additional Path Setup
There are some nuances with environment variables especially on windows.
(use-package exec-path-from-shell
:config
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))Handling url’s under WSL2
Cudos to this article
(when (and (eq system-type 'gnu/linux)
(string-match
"Linux.*Microsoft.*Linux"
(shell-command-to-string "uname -a")))
(setq
browse-url-generic-program "/mnt/c/Windows/System32/cmd.exe"
browse-url-generic-args '("/c" "start")
browse-url-browser-function #'browse-url-generic))Recent File Saving
(use-package recentf
:config
(setq recentf-save-file (expand-file-name "recentf" dbrady-savefile-dir))
(setq recentf-max-saved-items 50)
(setq recentf-max-menu-items 15)
(setq recentf-auto-cleanup 'never)
(recentf-mode +1))Paren Matching
Configuration for a bunch of built in packages.
(use-package paren
:config
(show-paren-mode +1))
Avy
Avy has one really useful function avy-goto-line which supports multiple
buffers
(use-package avy
:bind (("M-g f" . avy-goto-line)))Dired Mode
Dired mode is built in and powerful but easy to forget the commands and capabilities. Make things a bit easier to remember for me
;; dired-x comes with emacs but isn't loaded by default.
(require 'dired-x)
(setq-default dired-omit-files-p t) ; Buffer-local variable
(setq dired-omit-files (concat dired-omit-files "\\|^\\..+$"))
(setq dired-dwim-target t) ;; guess destination
(setq dired-recursive-copies 'always)
(setq dired-recursive-deletes 'always)
(define-key dired-mode-map (kbd "% f") 'find-name-dired)
(define-key dired-mode-map (kbd "% .") 'dired-omit-mode)
;; Changes to prevent navigating in dired mode from creating a bunch of buffers for every directory
(put 'dired-find-alternate-file 'disabled nil)
(add-hook 'dired-mode-hook
(lambda ()
(define-key dired-mode-map (kbd "^")
(lambda () (interactive) (find-alternate-file "..")))
(define-key dired-mode-map (kbd "e")
(lambda () (interactive) (find-alternate-file (dired-copy-filename-as-kill))))
(define-key dired-mode-map (kbd "f")
(lambda () (interactive) (find-alternate-file (dired-copy-filename-as-kill))))))
Text Scaling
default-text-scale allows you to quickly resize text. By default binds to
C-M-= and C-M– to increase and decrease the face size
(use-package default-text-scale
:config
(default-text-scale-mode))Ivy
Ivy is a completion framework
(use-package ivy
:config
(setq ivy-use-virtual-buffers t)
(setq ivy-use-selectable-prompt t)
(setq enable-recursive-minibuffers t)
(ivy-mode 1))Swiper
A generic completion front end
(use-package swiper
:bind (("C-s" . swiper)))Spray Speed Reader
Speed reading mode. Just enter the mode and use keys h/left arrow, l/right arrow, f and s for faster and slower, q quits
(require 'spray)
(setq spray-wpm 200)
PDF Tools
PDF Tools is a much better pdf viewer
(use-package pdf-tools
:config
(pdf-loader-install))(Yas) Snippets
Use yas-snippets for handy text completion
(use-package yasnippet
:ensure yasnippet-snippets
:config
(yas-global-mode 1))Org Mode
Set up for all things org-mode
Org and Extensions
Load org and other related packages.
(use-package org :ensure org-plus-contrib)
(use-package org-superstar)
(use-package org-edna)
(use-package org-super-agenda)
(use-package org-ql)
(use-package counsel)
(require 'org-habit)
Some basic configuration for Org Mode beginning with minor modes for spell
checking and replacing the *’s with various types of bullets.
(add-hook 'org-mode-hook (lambda () (org-superstar-mode 1)))
(define-key org-mode-map (kbd "C-c l") 'org-store-link)
(define-key org-mode-map (kbd "C-x n s") 'org-toggle-narrow-to-subtree)
(define-key org-mode-map (kbd "C-c C-j") 'counsel-org-goto)
(setq org-image-actual-width nil)
(setq org-modules (append '(org-protocol) org-modules))
(setq org-modules (append '(habit) org-modules))
(setq org-catch-invisible-edits 'smart)
(setq org-ctrl-k-protect-subtree t)
(set-face-attribute 'org-headline-done nil :strike-through t)
(setq org-return-follows-link t)Org File Locations
My setup now includes two org-directories under an umberlla OrgDocuments directory. They are personal and dcllp (work). The default opening setup is to default to personal.
(setq org-directory-personal "~/OrgDocuments/personal")
(setq org-directory-work "~/OrgDocuments/dcllp")
(setq org-directory org-directory-personal)
(setq org-agenda-files (directory-files-recursively org-directory "org$"))
(setq org-default-notes-file (concat org-directory "/index.org"))Org Roam
Likewise org-roam defaults to personal.
(setq org-roam-v2-ack t)
(use-package org-roam :ensure t
:custom
(org-roam-directory org-directory-personal)
:hook
(after-init . org-roam-setup))
;; required for org-roam bookmarklet
(require 'org-roam-protocol)
Org-roam Capture Templates
Starter pack. If there is only one, it uses automatically without asking.
(setq org-roam-capture-templates
'(("d" "default" plain "%?"
:if-new (file+head"%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}.org\" (current-time) t)"
"#+title: ${title}\n#+filetags %^G:\n")
:unnarrowed t)
("y" "yank" plain "%?"
:if-new (file+head"%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}.org\" (current-time) t)"
"#+title: ${title}\n#+filetags: %^G\n%c\n")
:unnarrowed t)
("o" "org-roam-it" plain "%?"
:if-new (file+head"%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}.org\" (current-time) t)"
"#+title: ${title}\n#+filetags:\n{ref}\n")
:unnarrowed t)))
Language Support
Setup babel to evaluate the languages / scripts I use.
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(ruby . t)
(python . t)
(sql . t)
(shell . t)
(clojure . t)
(gnuplot . t)))Don’t ask before evaluating code blocks.
(setq org-confirm-babel-evaluate nil)htmlize is used to ensure that exported code blocks use syntax highlighting.
Translate regular ol’ straight quotes to typographically-correct curly quotes when exporting.
(setq org-export-with-smart-quotes t)Settings related to source code blocks
(setq org-src-fontify-natively t) ;; syntax highlighting in source blocks
(setq org-src-tab-acts-natively t) ;; Make TAB act as if language's major mode.
(setq org-src-window-setup 'current-window) ;; Use the current window rather than popping open a new onwTask Handling and Agenda
Establishes the states and other settings related to task handling.
(setq org-enforce-todo-dependencies t)
(setq org-enforce-todo-checkbox-dependencies t)
(setq org-deadline-warning-days 7)
(setq org-todo-keywords '((sequence
"TODO(t)"
"STARTED(s)"
"WAITING(w)" "|"
"DONE(d)"
"SUSPENDED(u)"
"SKIPPED(k)")))
(setq org-log-done 'time)
(setq org-log-into-drawer t)
(setq org-log-reschedule 'note)
;; agenda settings
(setq org-agenda-span 1)
(setq org-agenda-start-on-weekday nil)
;; Normally bound to org-agenda-sunrise-sunset which is kinda useless
(add-hook 'org-agenda-mode-hook (lambda ()
(define-key org-agenda-mode-map (kbd "S") 'org-agenda-schedule)))
;; Normally bound to toggle diary inclusion which would never really do
(add-hook 'org-agenda-mode-hook (lambda ()
(define-key org-agenda-mode-map (kbd "D") 'org-agenda-deadline)))
Diary Settings
I’ve don’t use the diary file but it’s useful for holidays.
(setq calendar-bahai-all-holidays-flag nil)
(setq calendar-christian-all-holidays-flag t)
(setq calendar-hebrew-all-holidays-flag t)
(setq calendar-islamic-all-holidays-flag t)Calfw
Calfw generates useful calendar views suitable for printing or providing a more visual outlook on the day, week, two weeks, or month
(use-package calfw)
(use-package calfw-org)
(require 'calfw)
(require 'calfw-org)
(defun db:my-open-calendar ()
(interactive)
(cfw:open-calendar-buffer
:contents-sources
(list
(cfw:org-create-source "Green") ; orgmode source
;; (cfw:howm-create-source "Blue") ; howm source
;; (cfw:cal-create-source "Orange") ; diary source
;; (cfw:ical-create-source "Moon" "~/moon.ics" "Gray") ; ICS source1
;; (cfw:ical-create-source "gcal" "https://..../basic.ics" "IndianRed") ; google calendar ICS
)))
Org Edna
Org Edna provides more powerful org dependency management.
(org-edna-mode)
(defun db/org-edna-blocked-by-descendants ()
"Adds PROPERTY blocking this tasks unless descendants are DONE"
(interactive)
(org-set-property "BLOCKER" "descendants"))
(defun db/org-edna-blocked-by-ancestors ()
"Adds PROPERTY blocking this tasks unless ancestors are DONE"
(interactive)
(org-set-property "BLOCKER" "ancestors"))
(defun db/org-edna-current-id ()
"Get the current ID to make it easier to set up BLOCKER ids"
(interactive)
(set-register 'i (org-entry-get (point) "ID"))
(message "ID stored"))
(defun db/org-edna-blocked-by-id ()
"Adds PROPERTY blocking task at point with specific task ID"
(interactive)
(org-set-property "BLOCKER" (s-concat "ids(" (get-register 'i) ")")))
(define-key org-mode-map (kbd "C-c C-x <up>") 'db/org-edna-blocked-by-ancestors)
(define-key org-mode-map (kbd "C-c C-x <down>") 'db/org-edna-blocked-by-descendants)
(define-key org-mode-map (kbd "C-c C-x <left>") 'db/org-edna-current-id)
(define-key org-mode-map (kbd "C-c C-x <right>") 'db/org-edna-blocked-by-id)
(define-key org-mode-map (kbd "C-c C-x i") 'org-id-get-create)
;; override y (agenda year) with more useful todo yesterday for marking habits done prior day
(define-key org-agenda-mode-map (kbd "y") 'org-agenda-todo-yesterday)
Filter Refile Targets
I have monthly log files used to take notes / journal that are sources of refile items but not targets. They are named YYYY-MM(w).org
(defun db-filtered-refile-targets ()
"Removes month journals as valid refile targets"
(remove nil (mapcar (lambda (x)
(if (string-match-p "2[0-9]*\-[0-9]+w?" x)
nil x)) org-agenda-files)))
(setq org-refile-targets '((db-filtered-refile-targets :maxlevel . 10)))
Super Agenda Setup
Super Agenda allows for grouping of items that appear on the agenda. It doesn’t alter what will appear.
(setq org-agenda-skip-scheduled-if-done t
org-agenda-skip-deadline-if-done t
org-agenda-include-deadlines t
org-agenda-include-diary t
org-agenda-block-separator nil
org-agenda-compact-blocks t
org-agenda-start-with-log-mode nil)
(setq org-super-agenda-groups
'((:name "Today" :time-grid t :scheduled today :order 1)
(:name "Inflight Projects" :and (:deadline t :not (:todo "TODO") :regexp("PROJECT:") ) :order 2)
(:name "Important" :priority "A" :order 3)
(:name "Quick Picks" :effort< "0:15" :order 4)
;; (:name "With Caden" :and (:property ("OWNER" "caden") :scheduled future) :order 4)
(:name "Nice" :and (:priority<= "B" :scheduled future) :order 9)
(:name "Habits" :habit)))
(add-hook 'org-agenda-mode-hook 'org-super-agenda-mode)
Org Capture Setup
Org capture templates for Chrome org-capture from site.
Added this file: /.local/share/applications/org-protocol.desktop using the
following command:
cat > "${HOME}/.local/share/applications/org-protocol.desktop" << EOF
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
EOFand then run
update-desktop-database ~/.local/share/applications(require 'org-protocol)Setting up org-protocol handler. This page has best description:
This page has the best description. This is working in linux only, hence the todo.
(defun transform-square-brackets-to-round-ones(string-to-transform)
"Transforms [ into ( and ] into ), other chars left unchanged."
(concat
(mapcar #'(lambda (c) (if (equal c ?[) ?\( (if (equal c ?]) ?\) c))) string-to-transform))
)
(defvar my/org-contacts-template "* %(org-contacts-template-name)
:PROPERTIES:
:ADDRESS: %^{289 Cleveland St. Brooklyn, 11206 NY, USA}
:BIRTHDAY: %^{yyyy-mm-dd}
:EMAIL: %(org-contacts-template-email)
:NOTE: %^{NOTE}
:END:" "Template for org-contacts.")
;; if you set this variable you have to redefine the default t/Todo.
(setq org-capture-templates
`(
;; TODO (t) Todo template
("t" "Todo" entry (file+headline ,org-default-notes-file "Refile")
"* TODO %?"
:empty-lines 1)
;; Note (n) template
("n" "Note" entry (file+headline ,org-default-notes-file "Refile")
"* %? %(%i)"
:empty-lines 1)
;; Protocol (p) template
("p" "Protocol" entry (file+headline ,org-default-notes-file "Refile")
"* %^{Title}
Source: %u, %c
#+BEGIN_QUOTE
%i
#+END_QUOTE
%?"
:empty-lines 1)
;; Protocol Link (L) template
("L" "Protocol Link" entry (file+headline ,org-default-notes-file "Refile")
"* %? [[%:link][%(transform-square-brackets-to-round-ones \"%:description\")]]"
:empty-lines 1)
;; Goal (G) template
("G" "Goal" entry (file+headline ,org-default-notes-file "Refile")
"* GOAL %^{Describe your goal}
Added on %U - Last reviewed on %U
:SMART:
:Sense: %^{What is the sense of this goal?}
:Measurable: %^{How do you measure it?}
:Actions: %^{What actions are needed?}
:Resources: %^{Which resources do you need?}
:Timebox: %^{How much time are you spending for it?}
:END:"
:empty-lines 1)
;; Contact (c) template
("c" "Contact" entry (file+headline ,(concat org-directory "/contacts.org") "Contacts")
"* %(org-contacts-template-name)
:PROPERTIES:
:ADDRESS: %^{289 Cleveland St. Brooklyn, 11206 NY, USA}
:BIRTHDAY: %^{yyyy-mm-dd}
:EMAIL: %(org-contacts-template-email)
:TEL: %^{NUMBER}
:NOTE: %^{NOTE}
:END:"
:empty-lines 1)
))
Org Reveal
(use-package ox-reveal
:ensure ox-reveal
:ensure htmlize)Exporting
Allow export to markdown and beamer (for presentations).
(require 'ox-md)
(require 'ox-beamer)Presentations with org-tree-slide
(when (require 'org-tree-slide nil t)
(global-set-key (kbd "<f8>") 'org-tree-slide-mode)
(global-set-key (kbd "S-<f8>") 'org-tree-slide-skip-done-toggle)
(define-key org-tree-slide-mode-map (kbd "<f9>")
'org-tree-slide-move-previous-tree)
(define-key org-tree-slide-mode-map (kbd "<f10>")
'org-tree-slide-move-next-tree)
(define-key org-tree-slide-mode-map (kbd "<f11>")
'org-tree-slide-content)
(setq org-tree-slide-skip-outline-level 4)
(org-tree-slide-narrowing-control-profile)
(setq org-tree-slide-skip-done nil)
(setq org-image-actual-width nil))
Personal and Work Toggle
Need to add mode line display of context
(defun db/org-work-context ()
(interactive)
(setq org-directory org-directory-work)
(db/org-switch-context))
(defun db/org-personal-context ()
(interactive)
(setq org-directory org-directory-personal)
(db/org-switch-context))
(defun db/org-switch-context ()
(setq org-agenda-files (directory-files-recursively org-directory "org$"))
(setq org-default-notes-file (concat org-directory "/index.org"))
(setq org-roam-directory org-directory)
(setq org-roam-db-location (expand-file-name "org-roam.db" org-roam-directory))
(org-roam-db-sync))
Add a CREATED timestamp property to all TODOs
All of this comes from this gist. Would be nice if org mode just offered this as a local set up option.
;; Allow automatically handing of created/expired meta data.
(require 'org-expiry)
;; Configure it a bit to my liking
(setq
org-expiry-created-property-name "CREATED" ; Name of property when an item is created
org-expiry-inactive-timestamps t ; Don't have everything in the agenda view
)
(defun db/insert-created-timestamp()
"Insert a CREATED property using org-expiry.el for TODO entries"
(org-expiry-insert-created)
(org-back-to-heading)
(org-end-of-line)
(insert " "))
;; Whenever a TODO entry is created, I want a timestamp
;; Advice org-insert-todo-heading to insert a created timestamp using org-expiry
(defadvice org-insert-todo-heading (after db/created-timestamp-advice activate)
"Insert a CREATED property using org-expiry.el for TODO entries"
(db/insert-created-timestamp))
;; Make it active
(ad-activate 'org-insert-todo-heading)
(defadvice org-capture (after db/created-timestamp-advice activate)
"Insert a CREATED property using org-expiry.el for TODO entries"
; Test if the captured entry is a TODO, if so insert the created
; timestamp property, otherwise ignore
(when (member (org-get-todo-state) org-todo-keywords-1)
(db/insert-created-timestamp)))
(ad-activate 'org-capture)
;; Add feature to allow easy adding of tags in a capture window
(defun db/add-tags-in-capture()
(interactive)
"Insert tags in a capture window without losing the point"
(save-excursion
(org-back-to-heading)
(org-set-tags)))
Other Customizations
This section is for additional customizations.
Reading Email with mu4e
Load mu4e
So, mu4e isn’t in melpa (wtf) and has to be installed. Since switching to Fedora 34 (wayland) now…
sudo dnf install mu4e (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e")
(require 'mu4e)Contexts
I just have one context which is gmail.
(setq mu4e-contexts
`( ,(make-mu4e-context
:name "gmail"
:enter-func (lambda () (mu4e-message "Entering gmail context"))
:leave-func (lambda () (mu4e-message "Leaving gmail Context"))
;; we match based on the contact-fields of the message
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches msg
:to "donald.brady@gmail.com")))
:vars '( ( user-mail-address . "donald.brady@gmail.com" )
( user-full-name . "Donald Brady" )
( mu4e-compose-signature .
(concat
"Donald Brady\n"
"e: donald.brady@gmail.com\n"))))))
(setq mu4e-context-policy 'pick-first);; use mu4e for e-mail in emacs
(setq mail-user-agent 'mu4e-user-agent)
;; these must start with a "/", and must exist
;; (i.e.. /home/user/Maildir/gmail/Sent must exist) you use e.g. 'mu mkdir' and
;; 'mu init' to make the Maildirs if they don't already exist.
(setq mu4e-sent-folder "/gmail/Sent")
(setq mu4e-drafts-folder "/gmail/Drafts")
(setq mu4e-trash-folder "/gmail/Trash")
(setq mu4e-refile-folder "/gmail/Archive")
Fetching
Use mbsync for fetching email.
(setq mu4e-get-mail-command "mbsync -V gmail")Composing
Reading
Save attachments to Downloads
(setq mu4e-attachment-dir "~/Downloads") Use C-c C-o to open links
(define-key mu4e-view-mode-map (kbd "C-c C-o") 'mu4e~view-browse-url-from-binding) View images inline
(setq mu4e-view-show-images t)
(when (fboundp 'imagemagick-register-types)
(imagemagick-register-types))Archiving
Encryption
Sending
You will need to install msmtp and configure that as needed.
(setq message-send-mail-function 'message-send-mail-with-sendmail)
(setq message-sendmail-extra-arguments '("--read-envelope-from"))
(setq message-sendmail-f-is-evil 't)
(setq sendmail-program "msmtp") Org Agena Integration
org-mu4e lets me store links to emails. I use this to reference emails in
my TODO list while keeping my inbox empty. When storing a link to a message
in the headers view, link to the message instead of the search that resulted
in that view.
(require 'org-mu4e)
(setq org-mu4e-link-query-in-headers-mode nil)
Org Contacts
Use an org-contacts file to manage my address book.
(use-package org-contacts
:ensure nil
:after org
:custom (org-contacts-files '("~/OrgDocuments/personal/contacts.org")))
(setq mu4e-org-contacts-file (car org-contacts-files))
(add-to-list 'mu4e-headers-actions
'("org-contact-add" . mu4e-action-add-org-contact) t)
(add-to-list 'mu4e-view-actions
'("org-contact-add" . mu4e-action-add-org-contact) t)
Key Bindings
(global-set-key (kbd "C-c m") 'mu4e)
Openwith
Maps file extensions to applications
;; (use-package openwith)
;; (openwith-mode t)
;; (add-to-list 'mm-inhibit-file-name-handlers 'openwith-file-handler)
;; (setq openwith-associations '(("\\.pdf\\'" "pdfstudio2020" (file))))Projectile
Use projectile for projects navigation
(use-package projectile
:config
(setq projectile-switch-project-action #'projectile-dired)
(projectile-mode +1)
:bind ("C-c p p" . projectile-switch-project))Magit
(use-package magit
:config
(setq magit-push-always-verify nil)
:bind
(("C-x g" . magit-status)))Hippie Expand Setup
This is a more powerful completion system.
;; hippie expand is dabbrev expand on steroids
(setq hippie-expand-try-functions-list '(try-expand-dabbrev
try-expand-dabbrev-all-buffers
try-expand-dabbrev-from-kill
try-complete-file-name-partially
try-complete-file-name
try-expand-all-abbrevs
try-expand-list
try-expand-line
try-complete-lisp-symbol-partially
try-complete-lisp-symbol))
;; use hippie-expand instead of dabbrev
(global-set-key (kbd "M-/") #'hippie-expand)
(global-set-key (kbd "s-/") #'hippie-expand)
Blogging with Wordpress and Org2Blog
Org2Blog is a package for blogging directly from org-mode to wordpress which is about all I need to manage an online presence.
http://donald-brady.wordpress.com
(use-package org2blog
:ensure t
:config
(setq org2blog/wp-blog-alist
'(
("wordpress"
:url "https://donaldbrady.wordpress.com/xmlrpc.php"
:username "donald.brady@gmail.com")))
(setq org2blog/wp-image-upload t)
(setq org2blog/wp-image-thumbnails t)
:bind
(("C-c h" . org2blog-user-interface)))
RSS with elfeed
Install elfeed and load up my feeds stored in ~OrgDocuments/rss-feeds.org.
(use-package elfeed
:ensure elfeed-org
:config
(setq elfeed-set-max-connections 32)
(setq rmh-elfeed-org-files (list (expand-file-name "rss-feeds.org" org-directory-personal)))
(elfeed-org)
:bind
(("C-c r" . elfeed)
:map elfeed-show-mode-map
("o" . elfeed-show-visit)
:map elfeed-search-mode-map
("o" . elfeed-search-browse-url)))Programming
Python
(use-package python
:hook
(python-mode . flycheck-mode)
(python-mode . db/activate-pyvenv)
(python-mode . hs-minor-mode))
(use-package elpy
:ensure t
:init
(elpy-enable))Use pyvenv to support multiple python environments
(use-package pyvenv
:after python
:config
(defun db/activate-pyvenv ()
"Activate python environment according to the `.venv' file."
(interactive)
(pyvenv-mode)
(let* ((pdir (projectile-project-root)) (pfile (concat pdir ".venv")))
(if (file-exists-p pfile)
(pyvenv-workon (with-temp-buffer
(insert-file-contents pfile)
(nth 0 (split-string (buffer-string)))))))))Clojure
(use-package clojure-mode)
(use-package cider)Globally Set Keys
This section has all globally set keys unless they are related to a package or mode config.
;; use hippie-expand instead of dabbrev
(global-set-key (kbd "M-/") 'hippie-expand)
;; keyboard macros
(global-set-key (kbd "<f1>") 'start-kbd-macro)
(global-set-key (kbd "<f2>") 'end-kbd-macro)
(global-set-key (kbd "<f3>") 'call-last-kbd-macro)
;; org and org-roam keys
;; some should be mode local but I spend most of my in org mode so being lazy
(define-key global-map (kbd "\C-ca") 'org-agenda)
(define-key global-map (kbd "\C-cc") 'org-capture)
(define-key global-map (kbd "C-c n b") 'org-roam-buffer-toggle)
(define-key global-map (kbd "C-c n f") 'org-roam-node-find)
(define-key global-map (kbd "C-c n c") 'org-roam-capture)
(define-key global-map (kbd "C-c n g") 'org-roam-graph)
(define-key global-map (kbd "C-\\") 'org-previous-link)
(define-key global-map (kbd "C-c n i") 'org-roam-insert)
(define-key global-map (kbd "C-<return>") 'org-next-link)
(define-key global-map (kbd "C-c n d") 'org-roam-dailies-goto-today)
(define-key global-map (kbd "C-c n y") 'org-roam-dailies-goto-yesterday)
(define-key global-map (kbd "C-c n t") 'org-roam-dailies-goto-tomorrow)
(define-key global-map (kbd "C-c n i") 'org-roam-node-insert)
;; replace buffer-menu with ibuffer
(global-set-key (kbd "C-x C-b") 'ibuffer)
;; Lenovo Function Key Bindings
(global-set-key (kbd "<XF86Favorites>") 'bury-buffer) ;; The Star on F12
(global-set-key (kbd "<f12>") 'bury-buffer) ;; F12 on logi keybpard
;; M-0 to toggle hiding
(global-set-key (kbd "M-0") 'hs-toggle-hiding)
;; toggle line numbers
(global-set-key (kbd "C-c l") 'display-line-numbers-mode)
Load any Custom Code
If there is a file custom.el in .emacs directory load it
;; config changes made through the customize UI will be stored here
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file));; load any custom code for work.
(if (file-directory-p "~/OrgDocuments/dcllp")
(load (expand-file-name "lisp/deloitte.el" user-emacs-directory)))Theme
Kinda like this theme
(load-theme 'modus-operandi t)
(setq modus-themes-variable-pitch-ui t)
(setq modus-themes-variable-pitch-headings t)Test Garbage Collection Optimization
When entering the minibuffer sets it large so gc doesn’t happen when interacting. Once exited sets back to a smaller number to force more frequent collection.
(defun my-minibuffer-setup-hook ()
(setq gc-cons-threshold most-positive-fixnum))
(defun my-minibuffer-exit-hook ()
(setq gc-cons-threshold 800000))
(add-hook 'minibuffer-setup-hook #'my-minibuffer-setup-hook)
(add-hook 'minibuffer-exit-hook #'my-minibuffer-exit-hook)
Start a server
Finally start a server
(server-start)