#+TITLE: Emacs Configuration #+AUTHOR: Marc Pohling * Personal Information #+begin_src emacs-lisp (setq user-full-name "Marc Pohling" user-mail-address "marc.pohling@googlemail.com") #+end_src * Stuff to add / to fix - smartparens a sane default configuration for navigation, manipulation etc. is still necessary - Spaceline / Powerline or similar I want a pretty status bar! - Markdown mode There might be more than one package for this. - Git gutter: Do some configuration to make it useful (see given source link in the [[*Git][Section]] of gutter) Maybe only enable it for modes where it is likely I use git? - Some webmode stuff * 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 [[file:init.el][init.el]]. #+begin_src emacs-lisp (setq custom-file (expand-file-name "custom.el" user-emacs-directory)) (load custom-file) #+end_src Keep the .emacs.d clean by moving user files into a separate dir #+BEGIN_SRC emacs-lisp (setq bookmark-default-file "~/.emacs.d/user-dir/bookmarks") #+END_SRC * Theme ** Font Don't add the font in the work environment, which I am logged in as POH #+begin_src emacs-lisp (unless (string-equal user-login-name "POH") (set-face-attribute 'default nil :font "Hack-12") ) #+end_src ** Material Theme The [[https://github.com/cpaulik/emacs-material-theme][Material Theme]] comes in a dark and a light variant. Not too dark to be strenious though. b #+begin_src emacs-lisp (use-package material-theme :if (window-system) :defer t :ensure t ;; :init ;; (load-theme 'material t) ) #+end_src ** Apropospriate Theme Variants dark and light #+begin_src emacs-lisp (use-package apropospriate-theme :if (window-system) :defer t :ensure t :init (load-theme 'apropospriate-dark t) ) #+end_src * Sane defaults Sources for this section include [[https://github.com/magnars/.emacs.d/blob/master/settings/sane-defaults.el][Magnars Sveen]] and [[http://pages.sachachua.com/.emacs.d/Sacha.html][Sacha Chua]] These functions are useful. Activate them. #+begin_src emacs-lisp (put 'downcase-region 'disabled nil) (put 'upcase-region 'disabled nil) (put 'narrow-to-region 'disabled nil) (put 'dired-find-alternate-file 'disabled nil) #+end_src Answering just 'y' or 'n' should be enough. #+begin_src emacs-lisp (defalias 'yes-or-no-p 'y-or-n-p) #+end_src Keep all backup and auto-save files in one directory #+begin_src emacs-lisp (setq backup-directory-alist '(("." . "~/.emacs.d/backups"))) (setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t))) #+end_src UTF-8 please #+begin_src emacs-lisp (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) #+end_src Avoid tabs in place of multiple spaces (they look bad in TeX) and show empty lines #+begin_src emacs-lisp (setq-default indent-tabs-mode nil) (setq-default indicate-empty-lines t) #+end_src Turn off blinking cursor #+begin_src emacs-lisp (blink-cursor-mode -1) #+end_src Don't count two spaces after a period as the end of a sentence. Just one space is needed #+begin_src emacs-lisp (setq sentence-end-double-space nil) #+end_src Delete the region when typing, just like as we expect nowadays. #+begin_src emacs-lisp (delete-selection-mode t) #+end_src Auto-indent when pressing RET, just new-line when C-j #+begin_src emacs-lisp (define-key global-map (kbd "RET") 'newline-and-indent) (define-key global-map (kbd "C-j") 'newline) #+end_src Various stuff #+begin_src emacs-lisp (show-paren-mode t) (column-number-mode t) (setq uniquify-buffer-name-style 'forward) #+end_src * Prettier Line Wraps By default there is no line wrapping. M-q actually modifies the buffer, which might not be wanted. So: enable visual wrapping and keep indentation if there are any. #+begin_src emacs-lisp (global-visual-line-mode) (diminish 'visual-line-mode) (use-package adaptive-wrap :ensure t :init (when (fboundp 'adaptive-wrap-prefix-mode) (defun my-activate-adaptive-wrap-prefix-mode () "Toggle `visual-line-mode' and `adaptive-wrap-prefix-mode' simultaneously." (adaptive-wrap-prefix-mode (if visual-line-mode 1 -1))) (add-hook 'visual-line-mode-hook 'my-activate-adaptive-wrap-prefix-mode)) ) #+end_src * List buffers Ibuffer is the improved version of list-buffers. Make ibuffer the default buffer lister. [[http://ergoemacs.org/emacs/emacs_buffer_management.html][Source]] #+begin_src emacs-lisp (defalias 'list-buffers 'ibuffer) #+end_src Also auto refresh dired, but be quiet about it. [[http://whattheemacsd.com/sane-defaults.el-01.html][Source]] #+begin_src emacs-lisp (add-hook 'dired-mode-hook 'auto-revert-mode) (setq global-auto-revert-non-file-buffers t) (setq auto-revert-verbose nil) #+end_src * Org Mode ** Installation Although org mode ships with Emacs, the latest version can be installed externally. The configuration here follows the [[http://orgmode.org/elpa.html][Org mode ELPA Installation instructions.]] Added a hook to complete org functions, company-capf is necessary for this #+begin_src emacs-lisp (use-package org :ensure org-plus-contrib :init (add-hook 'org-mode-hook 'company/org-mode-hook) ) #+end_src To avoid problems executing source blocks out of the box. [[https://emacs.stackexchange.com/a/28604][Others have the same problem, too]]. The solution is to remove the .elc files form the package directory: #+begin_src sh: 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 #+end_src *** Org key bindings Set up some global key bindings that integrate with Org mode features #+begin_src emacs-lisp (bind-key "C-c l" 'org-store-link) (bind-key "C-c c" 'org-capture) (bind-key "C-c a" 'org-agenda) #+end_src Org overwrites RET and C-j, so I need to disable the rebinds #+begin_src emacs-lisp (define-key org-mode-map (kbd "RET") nil) ;;org-return (define-key org-mode-map (kbd "C-j") nil) ;;org-return-indent #+end_src *** Org agenda For a more detailed example [[https://github.com/sachac/.emacs.d/blob/83d21e473368adb1f63e582a6595450fcd0e787c/Sacha.org#org-agenda][see here]]. #+begin_src emacs-lisp (setq org-agenda-files (delq nil (mapcar (lambda (x) (and (file-exists-p x) x)) '("~/Archiv/Dokumente/Agenda")) ) ) #+end_src *** Org capture #+begin_src emacs-lisp (bind-key "C-c c" 'org-capture) (setq org-default-notes-file "~/Archiv/Dokumente/Notizen/notes.org") #+end_src ** 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. #+begin_src emacs-lisp (setq org-use-speed-commands t) (setq org-image-actual-width 550) (setq org-highlight-latex-and-related '(latex script entities)) #+end_src Hide emphasis markup (e.g. / ... / for italics, etc.) #+begin_src emacs-lisp (setq org-hide-emphasis-markers t) #+end_src Setting some environment paths #+begin_src emacs-lisp (if (string-equal user-login-name "POH") (progn (defvar PATH_ORG_FILES "p:/Eigene Dateien/Notizen/") (defvar PATH_ORG_JOURNAL "p:/Eigene Dateien/Notizen/Journal/") (defvar PATH_START "p:/Eigene Dateien/Notizen/")) ) #+end_src Sort org agenda by deadline and priority #+begin_src emacs-lisp (setq org-agenda-sorting-strategy (quote ((agenda deadline-up priority-down) (todo priority-down category-keep) (tags priority-down category-keep) (search category-keep))) ) #+end_src Custom todo-keywords, depending on environment #+begin_src emacs-lisp (if (string-equal user-login-name "POH") (setq org-todo-keywords '((sequence "OPEN" "TODO" "UNCLEAR" "|" "DONE" "IMPOSSIBLE"))) ) #+end_src Set locations of some org files #+begin_src emacs-lisp (if (string-equal user-login-name "POH") (progn (setq org-default-notes-file (concat PATH_ORG_FILES "notes.org")) (setq org-agenda-files (list(concat PATH_ORG_FILES "notes.org") (concat PATH_ORG_FILES "projects.org") (concat PATH_ORG_FILES "todo.org")))) ) #+end_src Work specific org-capture-templates #+begin_src emacs-lisp (if (string-equal user-login-name "POH") (setq org-capture-templates '(("t" "todo" entry (file (concat PATH_ORG_FILES "todo.org")) "** TODO %\\n%u\n%a\n") ("n" "note" entry (file org-default-notes-file)) ("p" "project" entry (file (concat PATH_ORG_FILES "projects.org")) "** OPEN %?\n%u\n** Beschreibung\n** Zu erledigen\n*** \n** Verlauf\n***" :clock-in t :clock-resume t) ("u" "Unterbrechung" entry (file org-default-notes-file) "* Unterbrechnung durch %? :Unterbrechung:\n%t" :clock-in t :clock-resume t))) ) #+end_src Customize the org agenda #+begin_src emacs-lisp (defun my-org-skip-subtree-if-priority (priority) "Skip an agenda subtree if it has a priority of PRIORITY. PRIORITY may be one of the characters ?A, ?B, or ?C." (let ((subtree-end (save-excursion (org-end-of-subtree t))) (pri-value (* 1000 (- org-lowest-priority priority))) (pri-current (org-get-priority (thing-at-point 'line t)))) (if (= pri-value pri-current) subtree-end nil))) (setq org-agenda-custom-commands '(("c" "Simple agenda view" ((tags "PRIORITY=\"A\"" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) (org-agenda-overriding-header "Hohe Priorität:"))) (agenda "" ((org-agenda-span 7) (org-agenda-start-on-weekday nil) (org-agenda-overriding-header "Nächsten 7 Tage:"))) (alltodo "" ((org-agenda-skip-function '(or (my-org-skip-subtree-if-priority ?A) (org-agenda-skip-if nil '(scheduled deadline)))) (org-agenda-overriding-header "Sonstige Aufgaben:")))))) ) #+end_src ** 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. #+begin_src emacs-lisp (setq org-tags-column 45) #+end_src ** Org babel languages This code block is linux specific. Loading languages which aren't available seems to be a problem #+begin_src emacs-lisp (cond ((eq system-type 'gnu/linux) (org-babel-do-load-languages 'org-babel-load-languages '( (C . t) (calc . t) (java . t) (js . t) (latex . t) (ledger . t) (beancount . t) (lisp . t) (python . t) (R . t) (ruby . t) (scheme . t) (shell . t) (sqlite . t) ) )) ) #+end_src #+begin_src emacs-lisp (defun my-org-confirm-babel-evaluate (lang body) "Do not confirm evaluation for these languages." (not (or (string= lang "beancount") (string= lang "C") (string= lang "emacs-lisp") (string= lang "java") (string= lang "ledger") (string= lang "python") (string= lang "R") (string= lang "sqlite")))) (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate) #+end_src I want plots! #+begin_src emacs-lisp (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) #+end_src ** 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 #+begin_src emacs-lisp (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) #+end_src * which-key Greatly increases discovery of functions! Click [[https://github.com/justbur/emacs-which-key][here]] for source and more info. Info in Emacs: M-x customize-group which-key #+begin_src emacs-lisp (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) ) #+end_src * 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 * Recentf Requires counsel #+begin_src emacs-lisp (use-package recentf ; :bind ("C-x C-r" . counsel-recentf) :config (recentf-mode t) (setq recentf-max-saved-items 200) ) #+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 #+begin_src emacs-lisp (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))) ) #+end_src The find-file replacement is nicer to navigate #+begin_src emacs-lisp (use-package counsel :ensure t :bind* ;; load counsel when pressed (("M-x" . counsel-M-x) ("C-x C-f" . counsel-find-file) ("C-x C-r" . counsel-recentf) ("C-c C-f" . counsel-git) ("C-c h f" . counsel-describe-function) ("C-c h v" . counsel-describe-variable) ("M-i" . counsel-imenu) ) ) #+end_src Swiper ivy-enhances isearch #+begin_src emacs-lisp (use-package swiper :ensure t :bind (("C-s" . swiper) ("C-c C-r" . ivy-resume) ) ) #+end_src * Latex Requirements for Linux: - Latex - pdf-tools #+begin_src emacs-lisp (unless (string-equal user-login-name "POH") (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"))) ) ) #+end_src For latex-preview-pane a patch might be necessary (as of 2017-10), see the issue [[https://github.com/jsinglet/latex-preview-pane/issues/37][here]] Update 2018-03: It seems to work without this patch. I will keep it here in case something breaks again. #+begin_src latex-preview-pane-update-p() --- (doc-view-revert-buffer nil t) +++ (revert-buffer-nil t 'preserve-modes) #+end_src After that M-x byte-compile-file #+begin_src emacs-lisp (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))) #+end_src * Emails Currently following tools are required: - notmuch (edit, read, tag, delete emails) - isync /mbsync (fetch or sync emails) After setting up mbsync, notmuch must be configured. Execute "notmuch" from the command line to launch the setup wizard. After it, "notmuch new" to create a new database, which will index the available local e-mails. TODO: - setup of mbsync on linux - setup of notmuch on linux - shell script for installation of isync and notmuch - more config for notmuch? - hydra for notmuch? - maybe org-notmuch? - some way to refresh the notmuch db before I run notmuch? #+begin_src emacs-lisp (unless (string-equal user-login-name "POH") (use-package notmuch :ensure t ) ) #+end_src * Personal Finances I picked ledger for my personal accounting and will test if it's beneficial over gnucash. ..and don't activate the modules at work. #+begin_src emacs-lisp (unless (string-equal user-login-name "POH") (use-package ledger-mode :ensure t :mode ("\\.ledger$" . ledger-mode) :init (setq clear-whole-transactions t) ) ) #+end_src Ok, maybe beancount is better. Since there is no debian package, it is an option to install it via pip. I picked /opt for the installation path #+begin_src shell sudo su cd /opt python3 -m venv beancount source ./beancount/bin/activate pip3 install wheel pip3 install beancount deactivate #+end_src When using beancount, it will automatically pick the created virtual environment. Activate the beancount mode #+begin_src emacs-lisp (unless (string-equal user-login-name "POH") ;; (add-to-list 'package-archives ;; '("beancount" . "/opt/beancount/elisp") t) ; (use-package beancount ; :load-path "/opt/beancount/elisp/" ;; :ensure t ; :mode ("\\.beancount$" . beancount-mode) (load "/home/marc/.emacs.d/elisp/beancount-mode.el") ; somehow load-path in use-package doesn't work (use-package beancount :load-path "/home/marc/.emacs.d/elisp" :mode ("\\.beancount$" . beancount-mode) :init (add-hook 'beancount-mode-hook 'company/beancount-mode-hook) (setenv "PATH" (concat "/opt/beancount/bin:" (getenv "PATH")) ) ) ) #+end_src For a nice frontend fava seems nice #+begin_src shell sudo su cd /opt python3 -m venv vava source ./vava/bin/activate pip3 install wheel pip3 install fava deactivate #+end_src Start fava with #+begin_src shell fava my_file.beancount #+end_src It is accessable on this URL: [[http://127.0.0.1:5000][Fava]] * Programming ** Common things List of plugins and settings which are shared between the language plugins Highlight whitespaces, tabs, empty lines. #+begin_src emacs-lisp (use-package whitespace :demand t :ensure nil :diminish whitespace-mode;;mode shall be active, but not shown in mode line :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)) ) #+end_src Disable Eldoc, it interferes with flycheck #+begin_src emacs-lisp (use-package eldoc :ensure nil :config (global-eldoc-mode -1) ) #+end_src Colorize colors as text with their value #+begin_src emacs-lisp (use-package rainbow-mode :ensure t :init (add-hook 'prog-mode-hook 'rainbow-mode t) :diminish rainbow-mode ;; :hook prog-mode ;; not working in use-package 2.3 :config (setq-default rainbow-x-colors-major-mode-list '()) ) #+end_src Highlight parens etc. for improved readability #+begin_src emacs-lisp (use-package rainbow-delimiters :ensure t :config (add-hook 'prog-mode-hook 'rainbow-delimiters-mode) ) #+end_src ** Smartparens Smartparens is a beast on its own, so it's worth having a dedicated section for it #+begin_src emacs-lisp (use-package smartparens :ensure t :diminish smartparens-mode :config (add-hook 'prog-mode-hook 'smartparens-mode) ) #+end_src ** Git [[https://magit.vc/manual/magit/index.html][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 #+begin_src emacs-lisp (use-package magit :ensure t :init ;; set git-path in work environment (if (string-equal user-login-name "POH") (setq magit-git-executable "P:/Eigene Dateien/Tools/Git/bin/git.exe") ) :defer t :bind (("C-x g" . magit-status)) ) #+end_src Display line changes in gutter based on git history. Enable it everywhere [[https://github.com/syohex/emacs-git-gutter][Source]] #+begin_src emacs-lisp (use-package git-gutter :ensure t :config (global-git-gutter-mode t) :diminish git-gutter-mode ) #+end_src Time machine lets me step through the history of a file as recorded in git. [[https://github.com/pidu/git-timemachine][Source]] #+begin_src emacs-lisp (use-package git-timemachine :ensure t ) #+end_src ** Company Mode Complete Anything! Activate company and make it react nearly instantly #+begin_src emacs-lisp (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) ;; (define-key company-active-map (kbd "TAB") #'company-complete-selection) ;; (define-key company-active-map (kbd "RET") nil) (company-tng-configure-default) ) #+end_src For a nicer suggestion box: company-box ([[https://github.com/sebastiencs/company-box][Source]]) It is only available for emacs 26 and higher. #+begin_src emacs-lisp (when (> emacs-major-version 25) (use-package company-box :ensure t :init (add-hook 'company-mode-hook 'company-box-mode))) #+end_src *** 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: ?? #+begin_src emacs-lisp (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) ) #+end_src (defun add-pcomplete-to-capf () (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)) ;; (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t) (add-hook 'org-mode-hook #'add-pcomplete-to-capf) Backend for Orgmode #+begin_src emacs-lisp (defun company/org-mode-hook() (set (make-local-variable 'company-backends) '(company-capf company-files)) (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t) (company-mode t) ) #+end_src Backend configuration for lisp-mode #+begin_src emacs-lisp (defun company/elisp-mode-hook() (set (make-local-variable 'company-backends) '((company-elisp company-dabbrev) company-capf company-files)) (company-mode t) ) #+end_src Backend configuration for beancount #+begin_src emacs-lisp (defun company/beancount-mode-hook() (set (make-local-variable 'company-backends) '(company-beancount)) ; '((company-beancount company-dabbrev) company-capf company-files)) (company-mode t) ) #+end_src *** Misc Company packages Addon to sort suggestions by usage #+begin_src emacs-lisp (use-package company-statistics :ensure t :after company :init (setq company-statistics-file "~/.emacs.d/user-dir/company-statistics-cache.el") :config (company-statistics-mode 1) ) #+end_src Get a popup with documentation of the completion candidate. For the popups the package pos-tip.el is used and automatically installed. [[https://github.com/expez/company-quickhelp][Company Quickhelp]] [[https://www.emacswiki.org/emacs/PosTip][See here for Pos-Tip details]] #+begin_src emacs-lisp (use-package company-quickhelp :ensure t :after company :config (company-quickhelp-mode 1) ) #+end_src Maybe add [[https://github.com/hlissner/emacs-company-dict][company-dict]]? It's a dictionary based on major modes, plus it has Yasnippet integration. ** Projectile Brings search functions on project level #+begin_src emacs-lisp (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))) ) #+end_src ** Yasnippet Snippets! TODO: yas-minor-mode? what's that? #+begin_src emacs-lisp (use-package yasnippet :ensure t :diminish yas-minor-mode :init (setq yas-snippet-dirs (concat user-emacs-directory "user-dir/snippets")) (yas-global-mode t) :mode ("\\.yasnippet" . snippet-mode) ; :config ; (yas-reload-all) ;; ensure snippets are updated and available, necessary when not using global-mode ) #+end_src ** Lisp #+begin_src emacs-lisp (add-hook 'emacs-lisp-mode-hook 'company/elisp-mode-hook) #+end_src Add some helpers to handle and understand macros #+begin_src emacs-lisp (use-package macrostep :ensure t :init (define-key emacs-lisp-mode-map (kbd "C-c e") 'macrostep-expand) (define-key emacs-lisp-mode-map (kbd "C-c c") 'macrostep-collapse)) #+end_src ** Python Systemwide following packages need to be installed: - venv The virtual environments need to have following modules installed: - jedi - epc - pylint #+begin_src emacs-lisp (use-package flycheck :ensure t :diminish flycheck-mode " ✓" :init (setq flycheck-emacs-lisp-load-path 'inherit) (add-hook 'after-init-hook #'global-flycheck-mode) (add-hook 'python-mode-hook (lambda () (semantic-mode 1) (flycheck-select-checker 'python-pylint))) ) #+end_src Automatically start python-mode when opening a .py-file. Not sure if python.el is better than python-mode.el. See [[https://github.com/jorgenschaefer/elpy/issues/887][here]] for info about ~python-shell-completion-native-enable~. The custom function is to run inferiour processes (do I really need that?), see [[https://emacs.stackexchange.com/questions/16361/how-to-automatically-run-inferior-process-when-loading-major-mode][here]]. Also limit the completion backends to those which make sense in Python. #+begin_src emacs-lisp (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) ) #+end_src 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 #+begin_src emacs-lisp (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) ) #+end_src 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 #+begin_src emacs-lisp (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) ) #+end_src 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/ [[https://github.com/marcwebbie/auto-virtualenv][Github source]] Depends on pyvenv #+begin_src emacs-lisp (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) ) #+end_src 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 #+begin_src emacs-lisp (use-package hydra :ensure t :bind ("C-c f" . hydra-flycheck/body) :config (setq-default hydra-default-hint nil) ) #+end_src ** Hydra Flycheck Flycheck is necessary, obviously #+begin_src emacs-lisp (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) ) #+end_src * Treemacs A file manager comparable to neotree. [[https://github.com/Alexander-Miller/treemacs][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! #+begin_src emacs-lisp (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)) ) #+end_src Treemacs-projectile is useful for uhh.. TODO explain! #+begin_src emacs-lisp (use-package treemacs-projectile :ensure t :defer t :config (setq treemacs-header-function #'treemacs-projectile-create-header) ) #+end_src TODO Hydrastuff or keybindings for functions: - treemacs-projectile - treemacs-projectile-toggle - treemacs-toggle - treemacs-bookmark - treemacs-find-file - treemacs-find-tag * Evil So... Evil Mode might be worth a try #+BEGIN_SRC emacs-lisp (use-package evil :ensure t :defer .1 ;; don't block emacs when starting, load evil immediately after startup :init (setq evil-want-integration nil) ;; required by evil-collection :config (evil-mode 0)) ;; for now deactivate per default #+END_SRC Evil-collection is a bundle of configs for different modes #+BEGIN_SRC emacs-lisp (use-package evil-collection :after evil :ensure t :config (evil-collection-init)) #+END_SRC * Window Handling Some tools to easen the navigation, creation and deletion of windows ** Ace-Window #+begin_src emacs-lisp (use-package ace-window :ensure t :init (global-set-key (kbd "C-x o") 'ace-window) ) #+end_src ** 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. #+begin_src emacs-lisp (use-package windmove :ensure t :config (windmove-default-keybindings) ) #+end_src * Quality of Life