* My dotfiles The config files are organized in emacs org files. They are tangled and symlinked to the appropriate directories. [[file:emacs-init.org::*tangle%20dotfiles][A hook]] tangles all files automatically on each save. ~emacs-init.org~ is special and not automatically tangled. The >100 src blocks make tangling take several seconds and ~org-babel-load-file~ in ~init.el~ tangles the init org file on each emacs start anyway. The symlinks can be created by manually running the appropriate src block in each configuration file. For an automated solution see below. ** Git Setup Every program's configuration lives in its own branch. All branches except the ones which end with a plus sign are then merged into =master=. To keep the git history clean, I use this script: #+begin_src shell :shebang "#!/bin/bash" :tangle tangle/merge.sh git checkout master git reset --hard init git branch -a | grep -v -e +$ -e master | sed "s/[ *] //" | xargs git merge git push --force origin master #+end_src ** Updating all tangled files This script (re-)tangles all =.org= and =.org.gpg= files. Run this in case the org files were updated outside of your local emacs (e.g. after pulling from a remote). Make sure to run it from the dotfiles directory. #+begin_src shell :shebang "#!/bin/bash" :tangle no emacs --batch --eval="\ (progn (require 'org) (let ((org-confirm-babel-evaluate nil)) (mapc 'org-babel-tangle-file (split-string \"$(ls *.org *.org.gpg)\"))))" #+end_src The above won't quite work for me as I use ~org-crypt~ in some configuration files and it also needs to be loaded & setup. For details see [[file:emacs-init.org][emacs-init.org]]. #+begin_src shell :shebang "#!/bin/bash" :tangle tangle/tangle.sh emacs --batch --eval="\ (progn (require 'org) (require 'org-crypt) (org-crypt-use-before-save-magic) (setq org-tags-exclude-from-inheritance '(\"crypt\")) (setq org-crypt-key \"F1EF502F9E81D81381B1679AF973BBEA6994521B\") (defun save-without-hook () (let ((before-save-hook nil)) (save-buffer))) (setq org-babel-pre-tangle-hook '(org-decrypt-entries save-without-hook)) (advice-add 'org-babel-tangle :after '(lambda (&rest r) (org-encrypt-entries) (save-without-hook))) (let ((org-confirm-babel-evaluate nil)) (mapc 'org-babel-tangle-file (split-string \"$(ls *.org *.org.gpg)\"))))" #+end_src ** Creating symlinks Each config files contains a source block which creates symlinks of the tangled configurations to their respective target locations. These blocks all have the ~:tangle tangle/symlink.sh~ and ~:shebang #!/bin/bash~ header arguments. The symlinks are created with ~ln -siv~ to list created symlinks (~-v~) and to ask when overwriting existing files (~-i~). To always replace all symlinks you can pipe ~yes~ into the ~ln -siv~ calls: ~yes | tangle/link.sh~. Make sure to run it from the dotfiles directory. As the symlink shell source blocks are scattered in all configuration files, all files are collected together using cat and then all blocks with the correct ~:tangle~ target are tangled. Unfortunately there is no function to directly only tangle blocks with a certain target, so this is not straightforward. #+begin_src shell :shebang "#!/bin/bash" :tangle tangle/link.sh catFile="concat.org" symlinkFile="tangle/symlink.sh" cat <(cat *.org) <(ls *.org.gpg | xargs gpg --decrypt) > $catFile emacs --batch --eval="\ (progn (require 'org) (let ((org-confirm-babel-evaluate nil)) (find-file \"$catFile\") (search-forward \":tangle $symlinkFile\") (org-babel-tangle '(16))))" rm $catFile $symlinkFile #+end_src * Window manager I use [[https://github.com/ch11ng/exwm][exwm]] and [[https://awesomewm.org/][awesome]] as my window managers. When doing a lot of coding and similar stuff I tend to use exwm as I will spend most of my time in emacs anyway.