General configuration

Table of Contents

These are my settings that are called in dotspacemacs/user-config. This function is called at the very end of Spacemacs initialization after layers configuration.

1. General

Hitting TAB always just indents the current line.

(setq tab-always-indent t)

Only one auth source for magit & co.

(setq auth-sources '("~/.netrc"))


(prefer-coding-system 'utf-8)

Enable line wrapping

(setq truncate-lines nil)

Enable key frequency tracking

(setq truncate-lines nil)
(keyfreq-mode 1)
(keyfreq-autosave-mode 1)
(setq keyfreq-excluded-commands

2. Appearance

Clean up spaceline contents.

(with-eval-after-load 'spaceline-segments

3. Major Mode Settings

3.1. Magit

Add to browsable URLs, therefore also create custom formatters, based on the normal github formatter.

(with-eval-after-load 'browse-at-remote

  (add-to-list 'browse-at-remote-remote-type-regexps '("^ioki-github\\.com$" . "ioki-github"))

  (defun browse-at-remote--format-region-url-as-ioki-github (repo-url location filename &optional linestart lineend)
    "URL formatted for github."
    (setq repo-url (s-replace "ioki-github" "github" repo-url))

     ((and linestart lineend)
      (format "%s/blob/%s/%s#L%d-L%d" repo-url location filename linestart lineend))
     (linestart (format "%s/blob/%s/%s#L%d" repo-url location filename linestart))
     (t (format "%s/tree/%s/%s" repo-url location filename))))

  (defun browse-at-remote--format-commit-url-as-ioki-github (repo-url commithash)
    "Commit URL formatted for github"
    (setq repo-url (s-replace "ioki-github" "github" repo-url))
    (format "%s/commit/%s" repo-url commithash))


Enable private Gitlab instance in magit forge

(with-eval-after-load 'forge
  (add-to-list 'forge-alist '("" "" "" forge-gitlab-repository))

3.2. LSP

Disable documentation overlays, use , h h instead.

(setq lsp-ui-doc-enable nil)

Disable file watches, as many folders will slow Emacs down.

(setq lsp-enable-file-watchers nil)

3.3. Ruby

Don't automatically insert the magic encoding comment.

(setq ruby-insert-encoding-magic-comment nil)

Keybinding to toggle between new and old hash syntax.

  "xrh" 'ruby-toggle-hash-syntax)

Underscore should be a word delimiter in slim.

(add-hook 'slim-mode-hook #'(lambda () (modify-syntax-entry ?_ "_")))

3.4. Elixir

Call elixir-format before save.

(add-hook 'elixir-mode-hook
          (lambda () (add-hook 'before-save-hook 'elixir-format nil t)))

Keybindings for Emacs ExUnit test runner.

(with-eval-after-load 'elixir-mode
  (spacemacs/declare-prefix-for-mode 'elixir-mode
    "mt" "tests" "testing related functionality")
  (spacemacs/set-leader-keys-for-major-mode 'elixir-mode
    "ta" 'exunit-verify-all
    "tb" 'exunit-verify
    "tr" 'exunit-rerun
    "tt" 'exunit-verify-single))

Pin the exunit window to the bottom.

(push '("*exunit-compilation*"
        :dedicated t
        :position bottom
        :stick t
        :height 0.4
        :noselect t)

3.5. Go

Set tab width to 4.

(setq-default tab-width 4)
(setq-default go-tab-width 4)

Call go-format before save.

(setq go-format-before-save t)

Enable flycheck for Go mode.

(add-hook 'go-mode-hook
          (lambda () (flycheck-mode 1)))

3.6. Web Mode

Intendation settings

(setq web-mode-css-indent-offset 2)
(setq js2-basic-offset 2)
(setq web-mode-markup-indent-offset 2)
(setq web-mode-code-indent-offset 2)
(setq css-indent-offset 2)
(setq-default js2-basic-offset 2
              js-indent-level 2)

3.7. JavaScript

Allow .dir-locals.el files to set prettier-related settings.

(put 'prettier-js-args 'safe-local-variable 'listp)
(put 'prettier-js-command 'safe-local-variable 'stringp)

Setup nodejs-repl.el keybindings.

(spacemacs/set-leader-keys-for-major-mode 'js2-mode "ne" 'nodejs-repl-send-last-expression)
(spacemacs/set-leader-keys-for-major-mode 'js2-mode "nl" 'nodejs-repl-send-line)
(spacemacs/set-leader-keys-for-major-mode 'js2-mode "nr" 'nodejs-repl-send-region)
(spacemacs/set-leader-keys-for-major-mode 'js2-mode "nb" 'nodejs-repl-send-buffer)
(spacemacs/set-leader-keys-for-major-mode 'js2-mode "nf" 'nodejs-repl-load-file)
(spacemacs/set-leader-keys-for-major-mode 'js2-mode "n'" 'nodejs-repl-switch-to-repl)
(spacemacs/set-leader-keys-for-major-mode 'js2-mode "ns" 'nodejs-repl-switch-to-repl)

3.8. TypeScript

Set indentation level to two spaces.

(setq typescript-indent-level 2)

3.9. SQL

The sqlfmt does not work very well with Postgres and is also outdated. This uses pgFormatter instead, installed with brew install pgformatter.

(setq sqlfmt-executable "pg_format")
(setq sqlfmt-options '())

4. Keybindings

4.1. Movements

Make evil-mode up/down operate in screen lines instead of logical lines.

(define-key evil-motion-state-map "j" 'evil-next-visual-line)
(define-key evil-motion-state-map "k" 'evil-previous-visual-line)

Also in visual mode…

(define-key evil-visual-state-map "j" 'evil-next-visual-line)
(define-key evil-visual-state-map "k" 'evil-previous-visual-line)

Move line under cursor with C-j/k.

(define-key evil-normal-state-map (kbd "C-j") 'drag-stuff-down)
(define-key evil-normal-state-map (kbd "C-k") 'drag-stuff-up)

Pressing H in any edit mode moves the cursor to the first non-blank character.

(evil-global-set-key 'normal "H" 'evil-first-non-blank)
(evil-global-set-key 'visual "H" 'evil-first-non-blank)
(evil-global-set-key 'motion "H" 'evil-first-non-blank)

Pressing L in any edit mode moves the cursor to the end of line.

(evil-global-set-key 'normal "L" (lambda () (interactive) (evil-end-of-line)))
(evil-global-set-key 'visual "L" (lambda () (interactive) (evil-end-of-line)))
(evil-global-set-key 'motion "L" (lambda () (interactive) (evil-end-of-line)))

Type g l to get a fast home row friendly jump menu to go to a visible line.

(define-key evil-motion-state-map "gl" 'evil-avy-goto-line)
(define-key evil-normal-state-map "gl" 'evil-avy-goto-line)

Type g o <char> <char> to get a fast home row friendly jump menu to go to a visible word that starts with these characters.

(define-key evil-motion-state-map "go" 'evil-avy-goto-char-2)
(define-key evil-normal-state-map "go" 'evil-avy-goto-char-2)

4.2. Macros

Type Q to execute the macro recorded to q.

(evil-global-set-key 'normal (kbd "Q") (lambda () (interactive) (evil-execute-macro 1 "@q")))

4.3. Dired

In dired, move to parent directory with h and open thing under cursor with l.

(with-eval-after-load 'dired
  (evil-define-key 'normal dired-mode-map
    "h" 'dired-up-directory
    "l" 'dired-find-file

4.4. Umlauts

Make Umlauts work like in the rest of MacOS.

(global-unset-key (kbd "M-s"))
(global-set-key (kbd "M-s")
                (lambda ()
                  "Insert ß."
                  (insert "ß")))
(global-unset-key (kbd "M-u"))
(global-set-key (kbd "M-u a")
                (lambda ()
                  "Insert ä."
                  (insert "ä")))
(global-set-key (kbd "M-u A")
                (lambda ()
                  "Insert Ä."
                  (insert "Ä")))
(global-set-key (kbd "M-u o")
                (lambda ()
                  "Insert ö."
                  (insert "ö")))
(global-set-key (kbd "M-u O")
                (lambda ()
                  "Insert Ö."
                  (insert "Ö")))
(global-set-key (kbd "M-u u")
                (lambda ()
                  "Insert ü."
                  (insert "ü")))
(global-set-key (kbd "M-u U")
                (lambda ()
                  "Insert Ü."
                  (insert "Ü")))

4.5. Misc

Set hippie expand from M-/ to ctrl-space.

(global-set-key (kbd "C-SPC") 'hippie-expand)

5. Emojis

Overwrite emoji settings.

(defun --set-emoji-font (frame)
  "Adjust the font settings of FRAME so Emacs can display emoji properly."
  (if (eq system-type 'darwin)
      ;; For NS/Cocoa
      (set-fontset-font t 'symbol (font-spec :family "Apple Color Emoji" :size 10) frame 'prepend)
    ;; For Linux
    (set-fontset-font t 'symbol (font-spec :family "Symbola") frame 'prepend)))

;; For when Emacs is started in GUI mode:
(--set-emoji-font nil)
;; Hook for when a frame is created with emacsclient
;; see
(add-hook 'after-make-frame-functions '--set-emoji-font)
(setq company-emoji-insert-unicode t)

6. Custom Functions

Helper functions that I call directly with SPC SPC.

6.1. Switch between Rails i18n files

This function switches between the German and the English translation file in a Rails project. Especially handy, if the project has a lot of files per language.

(defun switch-rails-i18n-file()
  "Switches to the i18n file in the other language"
  (if (search "/de/" buffer-file-name)
    (find-file (replace-regexp-in-string "/de/" "/en/" (buffer-file-name)))
    (find-file (replace-regexp-in-string "/en/" "/de/" (buffer-file-name))))

6.2. Exercism

Submits the current buffer to exercism and opens a temp buffer with the output and some additional information like the URL of the current practice.

(defun exercism-submit ()
  (with-output-to-temp-buffer "*exercism*"
    (princ(shell-command-to-string (concat "exercism submit " (buffer-file-name))))
  (pop-to-buffer "*exercism*"))

Fix the result buffer to the bottom and allow to close it with ctrl-g.

(push '("*exercism*"
        :dedicated t
        :position bottom
        :stick t
        :height 0.4
        :noselect t)

7. Finalization

In the end, satisfy the Spacemacs loading mechanism.

(provide 'my-general-config)

View Org Source

Back to Index

Author: Christian Bäuerlein

Created: 2022-01-07 Fri 21:16