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.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
elpa
.gitattributes
.gitignore
README.org
init.el

README.org

Emacs Configuration

Introduction

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))

General

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)

Server

Start Emacs in server mode:

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

Text

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)

Styling

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
  (global-hl-line-mode))

Buffer

Use ibuffer:

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

(setq-default ibuffer-saved-filter-groups
              `(("Default"
                 ("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)

Window

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 ()
  (interactive)
  (split-window-vertically)
  (other-window 1 nil)
  (switch-to-next-buffer)
  (other-window 1 nil))

(defun fw/hsplit-last-buffer ()
  (interactive)
  (split-window-horizontally)
  (other-window 1 nil)
  (switch-to-next-buffer)
  (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)

Org

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

Compilation

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."
  (interactive)
  (byte-recompile-directory (concat user-emacs-directory "elpa") 0))

Themes

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)

Markdown

(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))

Neotree

(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)
  (interactive)
  (delete-other-windows)
  (setq default-directory path)
  (neotree-dir path)
  (other-window 1))

Magit

(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)
  ad-do-it
  (delete-other-windows))

I’d like to spellcheck my commit messages:

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

Editorconfig

(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'."
  (interactive)
  (let ((thing (ivy-thing-at-point)))
    (when (use-region-p)
      (deactivate-mark))
    (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)

Company

(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)

Elfeed

(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)

Custom

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.