This repository contains my OSX dotfiles. They are version controlled using a git bare repository, as seen in this blog post. The setup goes something like this.
git init --bare $HOME/Dotfiles
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
config config --local status.showUntrackedFiles no
echo "alias config='/usr/bin/git --git-dir=$HOME/Dotfiles/ --work-tree=$HOME'" >> $HOME/.zshrc
The config alias can then be used to add and commit files, for example,
config add .zshrc
config commit -m 'Added zshrc'
config push
This section details my Emacs and Spacemacs configurations.
Some Emacs installs do not work with yabai tiling window manager or support retina pdf quality in PDFView. Emacs-mac does, so lets install it,
brew install emacs-mac --with-no-title-bars
Link emacs-mac to /usr/local/bin/emacs
.
brew link emacs-mac
This is a good blog post detailing the perks of using Emacs Mac Port.
Emacs/Emacs-plus install and pdf-tools renders low quality pdfs. Use emacs-mac and put this in user-config to fix,
;; default page width behavior
(setq-default pdf-view-display-size 'fit-page)
;; combined with emacs-mac this gives good odf quality for retina display
(setq pdf-view-use-scaling t)
Emacs profile switcher. Makes it easy to run multiple Emacs configs side by side.
~/.emacs-profile
sets the default config to use,~/.emacs-profiles.el
sets the all of the configs with the path to their directory and config file,- Use
C-c C-v t
on this src block to “tangle” i.e. create file~/.emacs-profiles.el
,
(("vanilla" . ((user-emacs-directory . "~/.emacs.d/configs/vanilla-emacs")))
("spacemacs-old-m" . ((user-emacs-directory . "~/spacemacs")
(env . (("SPACEMACSDIR" . "~/.emacs.d/configs/spacemacs-old")))))
("spacemacs-old-d" . ((user-emacs-directory . "~/spacemacs/develop")
(env . (("SPACEMACSDIR" . "~/.emacs.d/configs/spacemacs-old")))))
("spacemacs-master" . ((user-emacs-directory . "~/spacemacs")
(env . (("SPACEMACSDIR" . "~/.emacs.d/configs/spacemacs-base-new")))))
("org-config" . ((user-emacs-directory . "~/spacemacs/develop-org")
(env . (("SPACEMACSDIR" . "~/.emacs.d/configs/spacemacs-org-config")))))
("new-config" . ((user-emacs-directory . "~/spacemacs/develop")
(env . (("SPACEMACSDIR" . "~/.emacs.d/configs/spacemacs-base-new"))))))
Use C-c C-v t
on this src block to “tangle” i.e. create file ~/.emacs.d/emacs-client-server.sh
,
#!/usr/bin/env zsh
BG_RED=`tput setaf 1`
BG_GREEN=`tput setaf 2`
BOLD=`tput bold`
RESET=`tput sgr0`
# EMACS_CLIENT='/usr/local/opt/emacs-mac/bin/emacsclient'
# EMACS='/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/Emacs.sh'
# EMACS='/usr/local/opt/emacs-mac/Emacs.app'
# EMACS_CLIENT='/usr/local/opt/emacs-mac/bin/emacsclient -s '$HOME'/.emacs.d/server'
# EMACS_CLIENT='/usr/local/opt/emacs-mac/bin/emacsclient -s '$HOME'/.emacs.d/server/server '
# EMACS_CLIENT='/usr/local/opt/emacs-mac/bin/emacsclient'
# EMACS_CLIENT='/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/bin/emacsclient'
# EMACS='/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/bin/Emacs'
EMACS='/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/Emacs.sh'
EMACS_CLIENT='/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/bin/emacsclient'
DEFAULT_EVAL='(switch-to-buffer "*scratch*")'
# DEFAULT_ARGS="-e"
DEFAULT_ARGS=""
# DEFAULT_SERVER='-s '$HOME'/.emacs.d/server/server'
NO_WAIT='-nw'
# NO_WAIT='-n'
# Checks if there's a frame open
if pgrep Emacs &> /dev/null; then
echo "trying emacsclient"
/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/bin/emacsclient -nw "$@"
else
echo "trying emacs"
/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/Emacs.sh
fi
# function run_client(){
# ${EMACS_CLIENT} ${NO_WAIT} ${DEFAULT_ARGS} $@
# # if [ $# -ne 0 ]
# # then
# # echo "running basic emacsclient"
# # ${EMACS_CLIENT} ${NO_WAIT} $@
# # else
# # # ${EMACS_CLIENT} ${NO_WAIT} ${DEFAULT_ARGS} &> /dev/null
# # echo "Running full emacsclient"
# # ${EMACS_CLIENT} ${NO_WAIT} ${DEFAULT_ARGS} "${DEFAULT_EVAL}" &> /dev/null
# # fi
# }
Lets give it permissions,
chmod +x ~/.emacs.d/emacs-client-server.sh
and set an alias te
“terminal emacs” for emacsclient,
echo "alias te=\"~/.emacs.d/emacs-client-server.sh\"" >> ~/.zshrc
#!/usr/bin/env zsh
# Checks if there's a frame open
if pgrep Emacs &> /dev/null; then
echo "Opening emacsclient..."
/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/bin/emacsclient -nqc
else
echo "Opening Emacs..."
/usr/local/opt/emacs-mac/Emacs.app/Contents/MacOS/Emacs.sh
fi
chmod +x /.emacs.d/skhd-emacs-client-server.sh
yasnippet is configured through the auto-completion layer in spacemacs. Here’s a good blog post on yasnippets in spacemacs. I setup a private snippets directory that I can version control easily and enabled snippets in my completion popup,
(auto-completion :variables auto-completion-private-snippets-directory "~/.dotfiles/spacemacs-base-new/private/snippets" auto-completion-enable-snippets-in-popup t)
- To run a command in spacemacs
SPC :
, - Create a new snippet
yas-new-snippet
,- Tab-stops are defined by the $, followed by their tab index.
- $1 will be the first tab-stop, allowing for dynamic value insertion.
- Specifying the same tab-stop multiple times means that when inserting your dynamic value, it will appear in each place but only needing to be typed out once.
- $0 is always where the cursor ends, with no opportunity for value insertion.
Run helm-yas-create-snippet-on-region
when a bit of source code is selected in a source file to create a new snippet.
Run yas-reload-all
to load new snippets into memory.
Use SPC i s
to insert a snippet (“insert snippet”).
- Change themes using helm-themes
SPC T s
. - I added doom-themes and switch between them regularly.
dotspacemacs-additional-packages '(doom-themes)
Describe functions
are powerful Emacs introspection commands to get information
about functions, variables, modes etc. These commands are bound thusly:
Key binding | Description |
---|---|
SPC h d f | describe-function |
SPC h d k | describe-key |
SPC h d m | describe-mode |
SPC h d v | describe-variable |
Copied from documentation quick start quide.
I have put my org configuration into a layer called org-config
.
In the layers.el
file I include the org layer and setup reveal, projectile and hugo,
- reveal.js
Create reveal.js presentations in org mode. I currently add the following line to each
.org
file,#+REVEAL_ROOT: https://cdn.jsdelivr.net/npm/reveal.js@3.8.0
because I haven’t been able to successfully set the
org-re-reveal-root
variable to(sqetq org-re-reveal-root ~/reveal.js/)
. - org projectile
I chose to use per-project TODO files (called
TODOs.org
) and I added the below code to add them to the agenda,(with-eval-after-load 'org-agenda (require 'org-projectile) (mapcar '(lambda (file) (when (file-exists-p file) (push file org-agenda-files))) (org-projectile-todo-files)))
- hugo -
(configuration-layer/declare-layers '( (org :variables org-enable-reveal-js-support t org-enable-hugo-support t org-projectile-file "TODOs.org") ))
(setq org-directory "/Users/aidanscannell/Dropbox/org/" org-default-notes-file "~/Dropbox/org/notes.org" org-contacts-files '("~/Dropbox/org/contacts.org") org-todo-keywords '((sequence "SOMEDAY" "TODO" "PROGRESS" "|" "DONE" "DELEGATED" "CANCELLED")) ;; org-bullets-bullet-list '("■" "◆" "▲" "▶") org-startup-indented t ;; Keep the indentation well structured org-agenda-files '("/Users/aidanscannell/Dropbox/org/agenda") ;; set the agenda files. org-agenda-files '("/Users/aidanscannell/Dropbox/org/"))
Key binding | Description |
---|---|
SPC m x b | make region bold |
SPC m x c | make region code |
SPC m x i | make region italic |
SPC m x r | clear region emphasis |
SPC m x s | make region strike-through |
SPC m x u | make region underline |
SPC m x v | make region verbatim |
Key binding | Description |
---|---|
gj / gk | Next/previous element (heading) |
gh / gl | Parent/child element (heading) |
gH | Root heading |
ae | Element text object |
ar | Subtree text object |
M-j / M-k | Move heading |
M-h / M-l | Promote or demote heading |
M-J / M-K | Move subtree |
M-H / M-L | Promote or demote subtree |
>> / << | Promote or demote heading |
Key binding | Description |
---|---|
SPC m b . | Enter Babel Transient State |
SPC m b a | org-babel-sha1-hash |
SPC m b b | org-babel-execute-buffer |
SPC m b c | org-babel-check-src-block |
SPC m b d | org-babel-demarcate-block |
SPC m b e | org-babel-execute-maybe |
SPC m b f | org-babel-tangle-file |
SPC m b g | org-babel-goto-named-src-block |
SPC m b i | org-babel-lob-ingest |
SPC m b I | org-babel-view-src-block-info |
SPC m b j | org-babel-insert-header-arg |
SPC m b l | org-babel-load-in-session |
SPC m b n | org-babel-next-src-block |
SPC m b o | org-babel-open-src-block-result |
SPC m b p | org-babel-previous-src-block |
SPC m b r | org-babel-goto-named-result |
SPC m b s | org-babel-execute-subtree |
SPC m b t | org-babel-tangle |
SPC m b u | org-babel-goto-src-block-head |
SPC m b v | org-babel-expand-src-block |
SPC m b x | org-babel-do-key-sequence-in-edit-buffer |
SPC m b z | org-babel-switch-to-session |
SPC m b Z | org-babel-switch-to-session-with-code |
Key binding | Description |
---|---|
SPC a o p | Capture a TODO for the current project |
SPC u SPC a o p | Capture a TODO for any given project (choose from list) |
SPC p o | Go to the TODOs for the current project |
org-capture-mode
and org-src-mode
both support the confirm and abort
conventions.
Key binding | Description |
---|---|
SPC m <dotspacemacs-major-mode-leader-key> | confirm in org-capture-mode |
SPC m ' | confirm in org-src-mode |
SPC m c | confirm |
SPC m a | abort |
SPC m k | abort |
SPC m r | org-capture-refile in org-capture-mode |
The BibTeX layer includes the following packages,
- auctex
- org
- org-ref
- markdown-mode
- (helm-bibtex :requires helm)
- biblio
- biblio-core
I configured org-ref to use my mendeley .bib file at ~/Dropbox/org/ref/mendeley/library.bib
(setq org-ref-bibliography-notes "~/Dropbox/org/ref/notes.org"
org-ref-default-bibliography '("~/Dropbox/org/ref/mendeley/library.bib") ;; mendeley bibfile
;; TODO org-ref-default-bibliography is where org-ref looks for citations (mendeley bibfile) AND
;; where it writes bib information to e.g. using org-ref-pdf
org-ref-pdf-directory "~/Dropbox/org/ref/org-ref-pdfs/") ;; where org-ref saves papers
Org-ref provides a convenient function for opening pdfs belonging to mendeley bibtex items.
Mendely adds the pdf file path to a file
property in the bibtex entry and org-ref uses this.
(setq org-ref-get-pdf-filename-function 'org-ref-get-mendeley-filename)
I want to open these pdfs using pdf-tools so that I can view them inside emacs in pdf-view-mode.
(defun my/org-ref-open-pdf-at-point ()
"Open the pdf for bibtex key under point if it exists."
(interactive)
(let* ((results (org-ref-get-bibtex-key-and-file))
(key (car results))
(pdf-file (funcall org-ref-get-pdf-filename-function key)))
(if (file-exists-p pdf-file)
(find-file pdf-file)
(message "No PDF found for %s" key))))
(setq org-ref-open-pdf-function 'my/org-ref-open-pdf-at-point)
This function makes SPC m a
(TEX-run-all-command) open the pdf in pdf-view-mode in emacs.
In order to make sure that the bibliography is made when exporting org to latex-pdf,
(setq org-latex-pdf-process
'("pdflatex -interaction nonstopmode -output-directory %o %f"
"bibtex %b"
"pdflatex -interaction nonstopmode -output-directory %o %f"
"pdflatex -interaction nonstopmode -output-directory %o %f"))
I chose to use BibLaTeX over BibTeX,
(setq bibtex-dialect 'biblatex)
which requires the following at the top of the org file,
#+LATEX_HEADER: \usepackage[citestyle=authoryear-icomp,bibstyle=authoryear, hyperref=true,backref=false,maxcitenames=1,url=false,backend=bibtex,natbib=true] {biblatex}
#+LATEX_HEADER: \addbibresource{~/Dropbox/org/ref/mendeley/library.bib}
and uses,
\printbibliography
to generate the bibliography.
This section is for creating LaTeX docs outside of org-mode using auctex and reftex, which are built into the spacemacs LaTeX layer.
We want to use pdf-tools to open pdf files from tex,
(setq TeX-view-program-selection '((output-pdf "PDF Tools"))
TeX-source-correlate-start-server t)
(setq reftex-default-bibliography '("~/Dropbox/org/ref/mendeley/library.bib"))
Mention snippets.
;; Org mode settings
(setq org-directory "~/Dropbox/org/"
org-default-notes-file "~/Dropbox/org/notes.org"
org-contacts-files '("~/Dropbox/org/contacts.org")
org-todo-keywords '((sequence "TODO" "SOMEDAY" "PROGRESS" "|"
"DONE" "DELEGATED" "CANCELLED"))
org-startup-indented t ;; Keep the indentation well structured
org-agenda-files '("~/Dropbox/org/agenda/routine.org"
"~/Dropbox/org/1.todo.org"
"~/Dropbox/org/agenda/calendar.org"
"~/Dropbox/org/agenda/uni.org")) ;; set the agenda files.
;; Ignore scheduled tasks in task list view (SPC m t)
(setq org-agenda-todo-ignore-scheduled t)
(setq org-agenda-todo-ignore-deadlines t)
;; Skip finished items
(setq org-agenda-skip-deadline-if-done t)
(setq org-agenda-skip-scheduled-if-done t)
;; start agenda view from today
(setq org-agenda-start-on-weekday nil)
(setq org-agenda-span 10
org-agenda-start-on-weekday nil
org-agenda-start-day "-3d")
;; add the per project todo.org files to the agenda
(with-eval-after-load 'org-agenda
(require 'org-projectile)
(mapcar (lambda (file)
(when (file-exists-p file)
(push file org-agenda-files)))
(org-projectile-todo-files)))
- ”~/Dropbox/org/agenda/routine.org” contains my daily/weekly/monthly routines e.g. coffee, lunch, supervisor meeting.
- ”~/Dropbox/org/1.todo.org” contains all of my non project TODOs that I want to add to my agenda.
- ”~/Dropbox/org/agenda/calendar.org” contains events/deadlines/meetings that are not uni related.
- ”~/Dropbox/org/agenda/uni.org” contains event/deadlines/meetings that are uni related.
(setq org-agenda-files '("~/Dropbox/org/agenda/routine.org"
"~/Dropbox/org/1.todo.org"
"~/Dropbox/org/agenda/calendar.org"
"~/Dropbox/org/agenda/uni.org")) ;; set the agenda files.
;; Ignore scheduled tasks in task list view (SPC m t)
(setq org-agenda-todo-ignore-scheduled t)
(setq org-agenda-todo-ignore-deadlines t)
;; Skip finished items
(setq org-agenda-skip-deadline-if-done t)
(setq org-agenda-skip-scheduled-if-done t)
;; start agenda view from today
(setq org-agenda-start-on-weekday nil)
(setq org-agenda-span 10
org-agenda-start-on-weekday nil
org-agenda-start-day "-3d")
;; add the per project todo.org files to the agenda
(with-eval-after-load 'org-agenda
(require 'org-projectile)
(mapcar (lambda (file)
(when (file-exists-p file)
(push file org-agenda-files)))
(org-projectile-todo-files)))
;; Ignore scheduled tasks in task list view (SPC m t)
(setq org-agenda-todo-ignore-scheduled t)
(setq org-agenda-todo-ignore-deadlines t)
;; Skip finished items
(setq org-agenda-skip-deadline-if-done t)
(setq org-agenda-skip-scheduled-if-done t)
I set the default agenda to
- show 10 days (instead of 7),
- start 3 days before the current day,
(setq org-agenda-span 10
org-agenda-start-on-weekday nil
org-agenda-start-day "-3d")
If I want to see more days (e.g. 15) I can use 15 SPC a o a
.
I add all of the project TODO.org files with,
(with-eval-after-load 'org-agenda
(require 'org-projectile)
(mapcar (lambda (file)
(when (file-exists-p file)
(push file org-agenda-files)))
(org-projectile-todo-files)))
Emacs/spacemacs provides great git functionality by simply adding the git layer.
git
Magit status is incredible and I recommend everyone to check it out. I particularly like how easy it is to
- stage and unstage files,
- commit specific lines of a file,
- manage my branches and remotes,
- use git diff, rebase, cherry pick and log.
The git time machine is super useful SPC g t
. You can skip through previous commits and copy commit hashes which can be used with other magit functionality.
In ~/.config/skhd/skhdrc
create a keyboard shortcut for GUI Emacs,
cmd - m : /usr/local/bin/emacs cmd - m : ~/.emacs.d/emacs-client-server.sh
this will create a new server if non exist or connect to the one that is running. This dramatically improves startup time for subsequent Emacs instances.
I edited the spacemacs “~/.emacs.d/core/core-spacemacs.el”
(setq inhibit-startup-screen t) (spacemacs-buffer/goto-buffer) to (setq inhibit-startup-screen nil) ;; (setq inhibit-startup-screen t) ;; (spacemacs-buffer/goto-buffer)
In ~/.config/skhd/skhdrc
create a keyboard shortcut,
cmd - m : /usr/local/bin/emacs
Übersicht with a forked version of nibar.
git clone https://github.com/ryanyz10/ayu-nibar $HOME/Library/Application\ Support/Übersicht/widgets/ayu-nibar
brew install jq
- Installed SF Fonts
- Had to disabled weather widget and changed.
yabai -m signal --add event=space_changed \ action="osascript -e 'tell application \"Übersicht\" to refresh widget id \"nibar-spaces-primary-jsx\"'"
to
yabai -m signal --add event=space_changed \ action="osascript -e 'tell application \"Übersicht\" to refresh widget id \"ayu-nibar-spaces-primary-jsx\"'"