You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

25 KiB

Emacs Configuration

Personal Information

 (setq user-full-name "Marc Pohling"
       user-mail-address "marc.pohling@googlemail.com")

Update config in a running config

Two options:

  • reload the open file: M-x load-file, then press twice to accept the default filename, which is the currently opened

  • Point at the end of any sexp and press C-x C-e

Customize settings

Move the customize settings to its own file, instead of saving customize settings in init.el.

 (setq custom-file (expand-file-name "custom.el" user-emacs-directory))
 (load custom-file)

Theme

Font

 (set-face-attribute 'default nil :font "Hack-12")

Material Theme

The Material Theme comes in a dark and a light variant. Not too dark to be strenious though.

 (use-package material-theme
     :if (window-system)
     :defer t
     :ensure t
;;     :init
;;     (load-theme 'material t)
 )

Apropospriate Theme

Variants dark and light

 (use-package apropospriate-theme
     :if (window-system)
     :defer t
     :ensure t
     :init
     (load-theme 'apropospriate-dark t)
 )

Sane defaults

Sources for this section include Magnars Sveen and Sacha Chua

These functions are useful. Activate them.

 (put 'downcase-region 'disabled nil)
 (put 'upcase-region 'disabled nil)
 (put 'narrow-to-region 'disabled nil)
 (put 'dired-find-alternate-file 'disabled nil)

Answering just 'y' or 'n' should be enough.

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

Keep all backup and auto-save files in one directory

 (setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
 (setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))

UTF-8 please

 (setq locale-coding-system 'utf-8)
 (set-terminal-coding-system 'utf-8)
 (set-keyboard-coding-system 'utf-8)
 (set-selection-coding-system 'utf-8)
 (prefer-coding-system 'utf-8)

Avoid tabs in place of multiple spaces (they look bad in TeX) and show empty lines

 (setq-default indent-tabs-mode nil)
 (setq-default indicate-empty-lines t)

Turn off blinking cursor

 (blink-cursor-mode -1)

Don't count two spaces after a period as the end of a sentence. Just one space is needed

 (setq sentence-end-double-space nil)

Delete the region when typing, just like as we expect nowadays.

 (delete-selection-mode t)

Auto-indent when pressing RET, just new-line when C-j

 (define-key global-map (kbd "RET") 'newline-and-indent)
 (define-key global-map (kbd "C-j") 'newline)

Various stuff

 (show-paren-mode t)
 (column-number-mode t)

 (global-visual-line-mode)
 (diminish 'visual-line-mode)

 (setq uniquify-buffer-name-style 'forward)

List buffers

Ibuffer is the improved version of list-buffers. Make ibuffer the default buffer lister. Source

 (defalias 'list-buffers 'ibuffer)

Also auto refresh dired, but be quiet about it. Source

 (add-hook 'dired-mode-hook 'auto-revert-mode)
 (setq global-auto-revert-non-file-buffers t)
 (setq auto-revert-verbose nil)

Org Mode

Installation

Although org mode ships with Emacs, the latest version can be installed externally. The configuration here follows the Org mode ELPA Installation instructions. Added a hook to complete org functions, company-capf is necessary for this

 (use-package org
     :ensure org-plus-contrib
     :init
     (add-hook 'org-mode-hook
               (lambda ()
                 (add-to-list 'company-backends 'company-capf)
                 (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)
                 (company-mode t)))
 )

To avoid problems executing source blocks out of the box. Others have the same problem, too. The solution is to remove the .elc files form the package directory:

 var ORG_DIR=(let* ((org-v (cadr (split-string (org-version nil t) "@"))) (len (length org-v))) (substring org-v 1 (- len 2)))
 rm ${ORG_DIR}/*.elc

Org key bindings

Set up some global key bindings that integrate with Org mode features

 (bind-key "C-c l" 'org-store-link)
 (bind-key "C-c c" 'org-capture)
 (bind-key "C-c a" 'org-agenda)

Org overwrites RET and C-j, so I need to disable the rebinds

 (define-key org-mode-map (kbd "RET") nil) ;;org-return
 (define-key org-mode-map (kbd "C-j") nil) ;;org-return-indent

Org agenda

For a more detailed example see here.

 (setq org-agenda-files
     (delq nil
         (mapcar (lambda (x) (and (file-exists-p x) x))
                 '("~/Archiv/Dokumente/Agenda"))
     )
 )

Org capture

 (bind-key "C-c c" 'org-capture)
 (setq org-default-notes-file "~/Archiv/Dokumente/Notizen/notes.org")

Org Setup

Speed commands are a nice and quick way to perform certain actions while at the beginning of a heading. It's not activated by default.

See the doc for speed keys by checking out the documentation for speed keys in Org mode.

 (setq org-use-speed-commands t)
 (setq org-image-actual-width 550)
 (setq org-highlight-latex-and-related '(latex script entities))

Org tags

The default value is -77, which is weird for smaller width windows. I'd rather have the tags align horizontally with the header. 45 is a good column number to do that.

 (setq org-tags-column 45)

Org babel languages

 (org-babel-do-load-languages
'org-babel-load-languages
  '((python . t)
    (C . t)
    (calc . t)
    (latex . t)
    (java . t)
    (ruby . t)
    (lisp . t)
    (R . t)
    (scheme . t)
    (shell . t)
    (sqlite . t)
    (js . t)))

 (defun my-org-confirm-babel-evaluate (lang body)
     "Do not confirm evaluation for these languages."
     (not (or (string= lang "C")
              (string= lang "java")
              (string= lang "python")
              (string= lang "R")
              (string= lang "emacs-lisp")
              (string= lang "sqlite"))))
 (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)

I want plots!

 (use-package ess
   :ensure t
 )
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
(add-hook 'org-mode-hook 'org-display-inline-images)

Org babel/source blocks

I like to have source blocks properly syntax highlighted and with the editing popup window staying within the same window so all the windows don't jump around. Also, having the top and bottom trailing lines in the block is a waste of space, so we can remove them

I noticed that fontification doesn't work with markdown mode when the block is indented after editing it in the org src buffer - the leading #s for headers don't get fontified properly because they apppear as Org comments. Setting org-src-preserve-identation makes things consistent as it doesn't pad source blocks with leading spaces

 (setq org-src-fontify-natively t
       org-src-window-setup 'current-window
       org-src-strip-leading-and-trailing-blank-lines t
       org-src-preserve-indentation t
       org-src-tab-acts-natively t)

which-key

Greatly increases discovery of functions! Click here for source and more info. Info in Emacs: M-x customize-group which-key

 (use-package which-key
     :ensure t
     :diminish which-key-mode
     :config
     (which-key-mode)
     (which-key-setup-side-window-right-bottom)
     (which-key-setup-minibuffer)
     (setq which-key-idle-delay 0.5)
 )

Ido (currently inactive)

better completion

begin_src emacs-lisp (use-package ido :init (setq ido-enable-flex-matching t) (setq ido-everywhere t) (ido-mode t) (use-package ido-vertical-mode :ensure t :defer t :init (ido-vertical-mode 1) (setq ido-vertical-define-keys 'C-n-and-C-p-only) ) ) end_src

ivy / counsel / swiper

Flx is required for fuzzy-matching Is it really necessary? begin_src emacs-lisp (use-package flx) end_src

Ivy displays a window with suggestions for hotkeys and M-x

 (use-package ivy
     :ensure t
     :diminish
     (ivy-mode . "")                   ;; does not display ivy in the mode line
     :init
     (ivy-mode 1)
     :bind
     ("C-c C-r" . ivy-resume)
     :config
     (setq ivy-use-virtual-buffers t)  ;; recent files and bookmarks in ivy-switch-buffer
     (setq ivy-height 20)              ;; height of ivy window
     (setq ivy-count-format "%d/%d")   ;; current and total number
     (setq ivy-re-builders-alist       ;; regex replaces spaces with *
           '((t . ivy--regex-plus)))
 )

Counsel replaces:

  • M-x

  • C-x C-f find-file

  • C-c h f describe-function

  • C-c h v describe-variable

  • M-i imenu

The find-file replacement is nicer to navigate

 (use-package counsel
     :ensure t
     :bind*                           ;; load counsel when pressed
     (("M-x"     . counsel-M-x)
      ("C-x C-f" . counsel-find-file)
      ("C-c h f" . counsel-describe-function)
      ("C-c h v" . counsel-describe-variable)
      ("M-i"     . counsel-imenu)
     )
 )

Swiper ivy-enhances isearch

 (use-package swiper
     :ensure t
     :bind
     (("C-s"     . swiper)
      ("C-c C-r" . ivy-resume)
     )
 )

Recentf

Requires counsel

 (use-package recentf
     :bind ("C-x C-r" . counsel-recentf)
     :config
     (recentf-mode t)
     (setq recentf-max-saved-items 200)
 )

Latex

Requirements for Linux:

  • Latex

  • pdf-tools

 (use-package pdf-tools
   :ensure t
   :config
   (pdf-tools-install)
   (setq TeX-view-program-selection '((output-pdf "pdf-tools")))
   (setq TeX-view-program-list '(("pdf-tools" "Tex-pdf-tools-sync-view")))
 )

For latex-preview-pane a patch might be necessary (as of 2017-10), see the issue here Update 2018-03: It seems to work without this patch. I will keep it here in case something breaks again.

    latex-preview-pane-update-p()
---  (doc-view-revert-buffer nil t)
+++  (revert-buffer-nil t 'preserve-modes)

After that M-x byte-compile-file

 (use-package latex-preview-pane
   :ensure t
 )
 (setq auto-mode-alist
       (append '(("\\.tex$" . latex-mode)) auto-mode-alist))
 ;; one of these works
 (add-hook 'LaTeX-mode-hook 'latex-preview-pane-mode)
 (add-hook 'latex-mode-hook 'latex-preview-pane-mode)

 ;; necessary, because linum-mode isn't compatible and prints errors
 (add-hook 'pdf-view-mode-hook (lambda () (linum-mode -1)))

Programming

Common things

List of plugins and settings which are shared between the language plugins

Highlight whitespaces, tabs, empty lines.

 (use-package whitespace
   :demand t
   :ensure nil
   :init
   (dolist (hook '(prog-mode-hook
                   text-mode-hook
                   conf-mode-hook))
    (add-hook hook #'whitespace-mode))
;;   :hook ;;not working in use-package 2.3
;;   ((prog-mode . whitespace-turn-on)
;;    (text-mode . whitespace-turn-on))
   :config
   (setq-default whitespace-style '(face empty tab trailing))
 )

Disable Eldoc, it interferes with flycheck

 (use-package eldoc
   :ensure nil
   :config
   (global-eldoc-mode -1)
 )

Colorize colors as text with their value

 (use-package rainbow-mode
   :ensure t
   :init
   (add-hook 'prog-mode-hook 'rainbow-mode t)
;;   :hook prog-mode ;; not working in use-package 2.3
   :config
   (setq-default rainbow-x-colors-major-mode-list '())
 )

Magit

Link I want to do git stuff here, not in a separate terminal window

Little crashcourse in magit:

  • magit-init to init a git project

  • magit-status (C-x g) to call the status window

in status buffer:

  • s stage files

  • u unstage files

  • U unstage all files

  • a apply changed to staging

  • c c commit (type commit message, then C-c C-c to commit)

  • b b switch to another branch

  • P u git push

  • F u git pull

 (use-package magit
   :ensure t
   :defer t
   :bind (("C-x g" . magit-status))
 )

Company Mode

Complete Anything!

Activate company and make it react nearly instantly

 (use-package company
     :ensure t
     :config
     (setq-default company-minimum-prefix-length 1
                   company-tooltip-align-annotation t
                   company-tooltop-flip-when-above t
                   company-show-numbers t
                   company-idle-delay 0.1)
 )

Company backend hooks

Backend configuration for python-mode

Common backends are:

  • company-files: files & directory

  • company-keywords: keywords

  • company-capf: ??

  • company-abbrev: ??

  • company-dabbrev: dynamic abbreviations

  • company-ispell: ??

 (defun company/python-mode-hook()
   (set (make-local-variable 'company-backends)
        '((company-jedi company-dabbrev company-yasnippet) company-capf company-files))
;;        '((company-jedi company-dabbrev) company-capf company-files))
   (company-mode t)
 )

Backend configuration for lisp-mode

 (defun company/elisp-mode-hook()
   (set (make-local-variable 'company-backends)
        '((company-elisp company-dabbrev) company-capf company-files))
   (company-mode t)
 )

Misc Company packages

Addon to sort suggestions by usage

 (use-package company-statistics
     :ensure t
     :after company
     :config
     (company-statistics-mode 1)
 )

Get a popup with documentation of the completion candidate. For the popups the package pos-tip.el is used and automatically installed. Company Quickhelp See here for Pos-Tip details

 (use-package company-quickhelp
     :ensure t
     :after company
     :config
     (company-quickhelp-mode 1)
 )

Maybe add company-dict? It's a dictionary based on major modes, plus it has Yasnippet integration.

Projectile

Brings search functions on project level

(use-package projectile
:ensure t
:defer t
:bind
(("C-c p p" . projectile-switch-project)
("C-c p s s" . projectile-ag))
:init
(setq-default
projectile-cache-file (expand-file-name ".projectile-cache" user-emacs-directory)
projectile-known-projects-file (expand-file-name
                                ".projectile-bookmarks" user-emacs-directory))
:config
(projectile-mode t)
(setq-default
projectile-completion-system 'ivy
projectile-enable-caching t
projectile-mode-line '(:eval (projectile-project-name)))
)

Yasnippet

Snippets! TODO: yas-minor-mode? what's that?

 (use-package yasnippet
   :ensure t
   :init
   (yas-global-mode)
   :mode ("\\.yasnippet" . snippet-mode)
   :config
   (setq yas-snippet-dirs (concat user-emacs-directory "snippets"))
 )

Lisp

(add-hook 'emacs-lisp-mode-hook 'company/elisp-mode-hook)

Python

Systemwide following packages need to be installed:

  • venv

The virtual environments need to have following modules installed:

  • jedi

  • epc

  • pylint

 (use-package flycheck
     :ensure t
     :init
     (add-hook 'after-init-hook #'global-flycheck-mode)
     (add-hook 'python-mode-hook (lambda ()
                                     (semantic-mode 1)
                                     (flycheck-select-checker 'python-pylint)))
 )

Automatically start python-mode when opening a .py-file. Not sure if python.el is better than python-mode.el. See here for info about python-shell-completion-native-enable. The custom function is to run inferiour processes (do I really need that?), see here.

Also limit the completion backends to those which make sense in Python.

 (use-package python
     :mode ("\\.py\\'" . python-mode)
     :interpreter ("python" . python-mode)
     :init
     (add-hook 'python-mode-hook 'company/python-mode-hook)
     :config
     (setq python-shell-completion-native-enable nil)
 )

Jedi is a backend for python autocompletion and needs to be installed on the server:

  • pip install jedi

Code checks need to be installed, too:

  • pip install flake8

 (use-package company-jedi
     :defer t
;;     :after company
     :ensure t
     :config
     (setq jedi:environment-virtualenv (list (expand-file-name "~/Archiv/Programmierprojekte/Python/virtualenv/")))
     (setq jedi:python-environment-directory (list (expand-file-name "~/Archiv/Programmierprojekte/Python/virtualenv/")))
     (add-hook 'python-mode-hook 'jedi:setup)
     (setq jedi:complete-on-dot t)
     (setq jedi:use-shortcuts t)
;;     (add-hook 'python-mode-hook 'company/python-mode-hook)
 )

A wrapper to handle virtual environments. I strongly recommend to install virtual environments on the terminal, not through this wrapper, but changing venvs is fine.

TODO: automatically start an inferior python process or switch to it if already created

 (use-package pyvenv
     :ensure t
     :init
     (setenv "WORKON_HOME" (expand-file-name "~/Archiv/Programmierprojekte/Python/virtualenv/"))
     :config
     (pyvenv-mode t)
     (defun my/post-activate-hook()
         (setq jedi:environment-root pyvenv-virtual-env)
         (setq jedi:environment-virtualenv pyvenv-virtual-env)
         (setq jedi:tooltip-method '(nil)) ;; variants: nil or pos-tip and/or popup
         (setq python-shell-virtualenv-root pyvenv-virtual-env)
         ;; default traceback, other option M-x jedi:toggle-log-traceback
         ;; traceback is in  jedi:pop-to-epc-buffer
         (jedi:setup)
         (company/python-mode-hook)
         (setq jedi:server-args '("--log-traceback")))
;;         (add-to-list 'company-backends 'company-jedi)
;;         (add-to-list 'company-backends 'company-anaconda)
;;         (lambda ()
;;           (set (make-local-variable 'company-backends)
;;                '((company-jedi company-dabbrev) company-capf company-files)))
;;         (setq flycheck-checker 'python-pylint))
;;         (flycheck-select-checker 'python-pylint))
;;         (setq flycheck-checker 'python-flake8)
     (add-hook 'pyvenv-post-activate-hooks 'my/post-activate-hook)
 )

I want Emacs to automatically start the proper virtual environment. Required is a .python-version file with, content in the first line being path/to/virtualenv Github source

Depends on pyvenv

 (use-package auto-virtualenv
     :ensure t
;;     :after pyvenv
;;     :defer t
     :init
     (add-hook 'python-mode-hook 'auto-virtualenv-set-virtualenv)
     ;; activate on changing buffers
     ;; (add-hook 'window-configuration-change-hook 'auto-virtualenv-set-virtualenv)
     ;; activate on focus in
     ;; (add-hook 'focus-in-hook 'auto-virtualenv-set-virtualenv)
 )

Anaconda test

begin_src emacs-lisp (use-package anaconda-mode :ensure t :defer t :init (add-hook 'python-mode-hook 'anaconda-mode) ;; (add-hook 'python-mode-hook 'anaconda-eldoc-mode) :config (setq anaconda-eldoc-mode 1) ) end_src

begin_src emacs-lisp (use-package company-anaconda :ensure t :defer t :init (defun my/company-anaconda-hook() (add-to-list 'company-backends 'company-anaconda)) (add-hook 'python-mode-hook 'my/company-anaconda-hook) ) end_src

Hydra

Hydra allows grouping of commands

 (use-package hydra
     :ensure t
     :bind
     ("C-c f" . hydra-flycheck/body)
     :config
     (setq-default hydra-default-hint nil)
 )

Hydra Flycheck

Flycheck is necessary, obviously

 (defhydra hydra-flycheck (:color blue)

  "
^
^Flycheck^          ^Errors^            ^Checker^
^────────^──────────^──────^────────────^───────^───────────
_q_ quit            _<_ previous        _?_ describe
_m_ manual          _>_ next            _d_ disable
_v_ verify setup    _f_ check           _s_ select
^^                  ^^                  ^^
"
     ("q" nil)
     ("<" flycheck-previous-error :color red)
     (">" flycheck-next-error :color red)
     ("?" flycheck-describe-checker)
     ("d" flycheck-disable-checker)
     ("f" flycheck-buffer)
     ("m" flycheck-manual)
     ("s" flycheck-select-checker)
     ("v" flycheck-verify-setup)
 )

Treemacs

A file manager comparable to neotree. Github

It has some requirements, which gets used here anyway:

  • ace-window

  • hydra

  • projectile

  • python

I copied the configuration example from the github site. No idea what this executable-find is about. TODO check it out!

 (use-package treemacs
   :ensure t
   :defer t
   :config
   (setq treemacs-change-root-without-asking nil
         treemacs-collapse-dirs              (if (executable-find "python") 3 0)
         treemacs-file-event-delay           5000
         treemacs-follow-after-init          t
         treemacs-follow-recenter-distance   0.1
         treemacs-goto-tag-strategy          'refetch-index
         treemacs-indentation                2
         treemacs-indentation-string         " "
         treemacs-is-never-other-window      nil
         treemacs-never-persist              nil
         treemacs-no-png-images              nil
         treemacs-recenter-after-file-follow nil
         treemacs-recenter-after-tag-follow  nil
         treemacs-show-hidden-files          t
         treemacs-silent-filewatch           nil
         treemacs-silent-refresh             nil
         treemacs-sorting                    'alphabetic-desc
         treemacs-tag-follow-cleanup         t
         treemacs-tag-follow-delay           1.5
         treemacs-width                      35)
   (treemacs-follow-mode t)
   (treemacs-filewatch-mode t)
   (pcase (cons (not (null (executable-find "git")))
                (not (null (executable-find "python3"))))
     (`(t . t)
      (treemacs-git-mode 'extended))
     (`(t . _)
      (treemacs-git-mode 'simple)))
   :bind
   (:map global-map
         ([f8]        . treemacs-toggle))
 )

Treemacs-projectile is useful for uhh.. TODO explain!

 (use-package treemacs-projectile
   :ensure t
   :defer t
   :config
   (setq treemacs-header-function #'treemacs-projectile-create-header)
 )

TODO Hydrastuff or keybindings for functions:

  • treemacs-projectile

  • treemacs-projectile-toggle

  • treemacs-toggle

  • treemacs-bookmark

  • treemacs-find-file

  • treemacs-find-tag

Window Handling

Some tools to easen the navigation, creation and deletion of windows

Ace-Window

 (use-package ace-window
   :ensure t
   :init
   (global-set-key (kbd "C-x o") 'ace-window)
 )

Windmove

Windmove easens the navigation between windows. Here we are setting the default keybindings (shift+arrow)

CURRENTLY NOT WORKING, defaults are blocked. Also not sure if necessary when using ace-window.

 (use-package windmove
   :ensure t
   :config
   (windmove-default-keybindings)
 )

Quality of Life