Skip to content
No description, website, or topics provided.
Emacs Lisp
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Emacs Configuration


I am currently running GNU Emacs 25.3.1.

OS Detection

(setq fw/is-linux (eq system-type 'gnu/linux)
      fw/is-windows (eq system-type 'windows-nt))


Simplify confirmation:

(fset 'yes-or-no-p 'y-or-n-p)

Reload a file if it changed on disk:

(global-auto-revert-mode t)

Disable backup and auto save files:

(setq backup-inhibited t)
(setq auto-save-default nil)

Disable audio bell:

(setq visible-bell t)

Hide startup message and empty scratch buffer:

(setq inhibit-startup-message t)
(setq initial-scratch-message nil)

Increase the garbage collection threshold:

(setq gc-cons-threshold 20000000)

Always start in fullscreen:

(add-to-list 'initial-frame-alist '(fullscreen . maximized))

I used to get errors in the login process when doing a git push on Windows. This should fix it:

(if fw/is-windows
    (setenv "GIT_ASKPASS" "git-gui--askpass"))

Make scrolling a little bit smoother:

(setq mouse-wheel-progressive-speed nil)


Start Emacs in server mode:

(require 'server)
(if (not (server-running-p)) (server-start))


Prefer UTF-8:

(prefer-coding-system 'utf-8)

Set default line length:

(setq-default fill-column 80)

Overwrite selected text when typing:

(delete-selection-mode t)

Ensure that files end with a new line:

(setq require-final-newline t)

Mark matching pairs of parentheses:

(show-paren-mode t)
(setq show-paren-delay 0.0)

Spaces > Tabs:

(setq-default indent-tabs-mode nil)

Use single space after a sentence:

(setq sentence-end-double-space nil)

Delete trailing whitespace on save:

(add-hook 'before-save-hook 'delete-trailing-whitespace)


Hide toolbar:

(tool-bar-mode -1)

Set the default font:

(set-face-attribute 'default nil
                    :family "Roboto Mono Medium"
                    :height 120
                    :weight 'normal
                    :width 'normal)

Enable column numbers:

(setq column-number-mode t)

Highlight current line:

(when window-system


Use ibuffer:

(global-set-key (kbd "C-x C-b") 'ibuffer)

(setq-default ibuffer-saved-filter-groups
                 ("Temporary" (name . "\*.*\*"))
                 ("Magit" (name . "^magit"))
                 ("Dired" (mode . dired-mode))

(add-hook 'ibuffer-mode-hook
          (lambda ()
            (ibuffer-auto-mode 1)
            (ibuffer-switch-to-saved-filter-groups "Default")))

(setq ibuffer-show-empty-filter-groups nil)
(setq ibuffer-expert t)

C-x k should kill the current buffer:

(global-set-key (kbd "C-x k") 'kill-this-buffer)


By default, split-window-vertically and split-window-horizontally display the current buffer twice. Most of the time I’ll change the buffer in the second window, which is why this snippet looks really handy:

(defun fw/vsplit-last-buffer ()
  (other-window 1 nil)
  (other-window 1 nil))

(defun fw/hsplit-last-buffer ()
  (other-window 1 nil)
  (other-window 1 nil))

(global-set-key (kbd "C-x 2") 'fw/vsplit-last-buffer)
(global-set-key (kbd "C-x 3") 'fw/hsplit-last-buffer)


General org configuration:

(setq org-catch-invisible-edits 'smart)
(setq org-log-into-drawer t)
(setq initial-major-mode 'org-mode)

Improve org’s source code blocks:

(setq org-src-fontify-natively t)
(setq org-src-tab-acts-natively t)
(setq org-src-window-setup 'current-window)

The calendar should use my native language. The calendar-set-date-style line changes the date format in %%(diary.anniversary ...):

(calendar-set-date-style 'iso)
(setq calendar-week-start-day 1
      calendar-day-name-array ["Sonntag" "Montag" "Dienstag" "Mittwoch"
                               "Donnerstag" "Freitag" "Samstag"]
      calendar-month-name-array ["Jänner" "Februar" "März" "April" "Mai"
                                 "Juni" "Juli" "August" "September" "Oktober" "November" "Dezember"])

(setq parse-time-months '(("jän" . 1) ("feb" . 2) ("mär" . 3)
                          ("apr" . 4) ("mai" . 5) ("jun" . 6)
                          ("jul" . 7) ("aug" . 8) ("sep" . 9)
                          ("okt" . 10) ("nov" . 11) ("dez" . 12)
                          ("jänner" . 1) ("februar" . 2) ("märz" . 3)
                          ("april" . 4) ("mai" . 5) ("juni" . 6)
                          ("juli" . 7) ("august" . 8)
                          ("september" . 9) ("oktober" . 10)
                          ("november" . 11) ("dezember" . 12)))

(setq parse-time-weekdays '(("so" . 0) ("mo" . 1) ("di" . 2)
                            ("mi" . 3) ("do" . 4) ("fr" . 5)
                            ("sa" . 6) ("sonntag" . 0) ("montag" . 1)
                            ("dienstag" . 2) ("mittwoch" . 3)
                            ("donnerstag" . 4) ("freitag" . 5)
                            ("samstag" . 6)))

I’ve found this snippet of Austrian holidays in Karl Void’s configuration:

(setq holiday-austria-holidays '((holiday-fixed  1  1 "Neujahr (frei)")
                                 (holiday-fixed  1  6 "Heilige Drei Könige (frei)")
                                 (holiday-easter-etc 1 "Ostermontag (frei)")
                                 (holiday-easter-etc -46 "Aschermittwoch")
                                 (holiday-easter-etc -2 "Karfreitag")
                                 (holiday-fixed  5  1 "Österreichischer Staatsfeiertag (frei)")
                                 (holiday-easter-etc 39 "Christi Himmelfahrt (frei)")
                                 (holiday-easter-etc 50 "Pfingstmontag (frei)")
                                 (holiday-easter-etc 60 "Fronleichnam (frei)")
                                 (holiday-fixed  8 15 "Mariä Himmelfahrt (frei)")
                                 (holiday-fixed 10 26 "Nationalfeiertag (frei)")
                                 (holiday-fixed 11  1 "Allerheiligen (frei)")
                                 (holiday-fixed 12  8 "Maria Empfängnis (frei)")
                                 (holiday-fixed 12 24 "Heiliger Abend")
                                 (holiday-fixed 12 25 "Erster Weihnachtstag (frei)")
                                 (holiday-fixed 12 26 "Zweiter Weihnachtstag (frei)")))

(setq holiday-local-holidays holiday-austria-holidays)
(setq calendar-holidays (append holiday-local-holidays holiday-other-holidays))

Basic agenda configuration with a custom agenda view:

(setq org-agenda-skip-scheduled-if-done t)
(global-set-key (kbd "C-c a") 'org-agenda)

(setq org-agenda-custom-commands
      '(("." "Overview"
         ((agenda ""
                  ((org-agenda-overriding-header "Kalender\n")))
          (todo ""
                ((org-agenda-overriding-header "\nOffen\n")
                 (org-agenda-block-separator nil)
                 (org-agenda-sorting-strategy '(todo-state-up))
                 (org-agenda-todo-ignore-scheduled 'all)))))))

External Packages


I have excluded *.elc files in this git repository, which is why I need a function to compile new packages:

(defun fw/compile-elpa-dir ()
  "Byte-compile all packages."
  (byte-recompile-directory (concat user-emacs-directory "elpa") 0))


I like light themes:

(load-theme 'sanityinc-tomorrow-day t)

with just some minor adjustments:

(set-face-attribute 'org-agenda-structure nil :inherit 'default :height 1.25)


(autoload 'markdown-mode "markdown-mode"
  "Major mode for editing Markdown files" t)
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("CHANGELOG\\.md\\'" . markdown-mode))

(autoload 'gfm-mode "markdown-mode"
  "Major mode for editing GitHub Flavored Markdown files" t)
(add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))


(setq neo-autorefresh nil)
(global-set-key (kbd "<f8>") 'neotree-toggle)
(global-set-key (kbd "<f9>") 'neotree-dir)

By defining #+LINK: dir elisp:(fw/visit-directory "%s") at the top of a org-mode file, I can create links which let me jump into a specific directory using this helper method:

(defun fw/visit-directory (path)
  (setq default-directory path)
  (neotree-dir path)
  (other-window 1))


(global-set-key (kbd "C-x g") 'magit-status)
(setq git-commit-summary-max-length 50)
(setq git-commit-fill-column 72)
(setq magit-completing-read-function 'ivy-completing-read)

Howard Abrams wrote a nice snippet which lets magit-status open in fullscreen:

(defadvice magit-status (around magit-fullscreen activate)
  (window-configuration-to-register :magit-fullscreen)

I’d like to spellcheck my commit messages:

(add-hook 'git-commit-mode-hook 'flyspell-mode)


(editorconfig-mode 1)

Ivy, Counsel & Swiper

(counsel-mode 1)
(setq ivy-count-format "%d/%d ")
(global-set-key (kbd "C-x b") 'ivy-switch-buffer)
(global-set-key (kbd "C-c f") 'counsel-git)
(global-set-key (kbd "C-c g") 'counsel-rg)
(global-set-key (kbd "C-s") 'swiper)
(global-set-key (kbd "C-r") 'swiper-backward)

C-x C-f feels clunky, let’s use C-x f instead:

(global-set-key (kbd "C-x f") 'counsel-find-file)

Ivy 0.12.0 did add some command extensions such as swiper-thing-at-point, which is based on ivy-thing-at-point. I’d like to use counsel-rg through ivy-thing-at-point:

(defun fw/counsel-rg-thing-at-point ()
  "`counsel-rg' with `ivy-thing-at-point'."
  (let ((thing (ivy-thing-at-point)))
    (when (use-region-p)
    (counsel-rg thing)))

(global-set-key (kbd "M-s _") 'fw/counsel-rg-thing-at-point)
(global-set-key (kbd "M-s .") 'swiper-isearch-thing-at-point)


(setq company-idle-delay 0.1)
(setq company-minimum-prefix-length 3)
(setq company-show-numbers t)
(global-company-mode t)

The dabbrev backend has some inconvenient default settings (e.g. its suggestions get downcased, even if notations such as camel casing are used):

(setq company-dabbrev-downcase nil)
(setq company-dabbrev-ignore-case nil)


(global-set-key (kbd "C-x w") 'elfeed)

Doom Modeline

This modeline uses all-the-icons, which can be installed using M-x all-the-icons-install-fonts.

Alternative: All fonts can be found here.

(doom-modeline-mode 1)

Do not show method names in the modeline:

(setq which-func-modes nil)


Additional configuration that is only relevant on a particular machine should be stored in /.emacs.d/custom.el.

(when (file-exists-p "~/.emacs.d/custom.el")
  (load-file "~/.emacs.d/custom.el"))
You can’t perform that action at this time.