Files
.emacs.d/README.org
2020-04-11 11:16:53 +02:00

984 lines
34 KiB
Org Mode

#+TITLE: Emacs Configuration
This is my configuration for the emacs editor.
* Set up UI
Remove all those UI elements. They do not look good and waste space.
#+BEGIN_SRC emacs-lisp
(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tooltip-mode -1)
(fringe-mode -1)
#+END_SRC
Make the frame a bit larger
#+BEGIN_SRC emacs-lisp
(when window-system (set-frame-size (selected-frame) 180 60))
#+END_SRC
* Set up package repositories
** Require package support
State that we will need package support and define a macro for adding package repos to the archives
#+BEGIN_SRC emacs-lisp
(require 'package)
(defmacro append-to-list (target suffix)
"Append SUFFIX to TARGET in place."
`(setq ,target (append ,target ,suffix)))
#+END_SRC
** Add package repos
#+BEGIN_SRC emacs-lisp
(append-to-list package-archives
'(("melpa" . "http://melpa.org/packages/")
("org-elpa" . "https://orgmode.org/elpa/")))
#+END_SRC
** Ensure ~use-package~ command is present
#+BEGIN_SRC emacs-lisp
(package-initialize)
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(require 'use-package)
(setq
use-package-always-ensure t
use-package-verbose t)
(use-package gnu-elpa-keyring-update)
#+END_SRC
* Set Backup Location
Emacs, by default clutters the file system with backup files.
We do not want them to be right next to the actual file, so we tell emacs to use dedicated directory to store them.
While we are at it, we also set rule for how many version emacs should keep as backups.
#+BEGIN_SRC emacs-lisp
(setq backup-directory-alist `(("." . "~/.emacs-backup")))
(setq backup-by-copying t)
(setq delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
#+END_SRC
* Define useful functions
** Edit the config file
A simple funtion to open this file for quick editing.
#+BEGIN_SRC emacs-lisp
(defun edit-config ()
(interactive)
(find-file "~/.emacs.d/README.org"))
#+END_SRC
** Reformat a whole buffer
Reindet the whole buffer with ~F12~
#+BEGIN_SRC emacs-lisp
(defun indent-buffer ()
(interactive)
(save-excursion
(indent-region (point-min) (point-max) nil)))
(global-set-key [f12] 'indent-buffer)
#+END_SRC
** Split windows and immediately switch to it
#+BEGIN_SRC emacs-lisp
(defun split-right-and-enter ()
"Split the window to the right and enter it."
(interactive)
(split-window-right)
(other-window 1))
(defun split-below-and-enter ()
"Split the window down and enter it."
(interactive)
(split-window-below)
(other-window 1))
#+END_SRC
** Quick buffer switching
#+BEGIN_SRC emacs-lisp
(defun switch-to-previous-buffer ()
"Switch to previously open buffer. Repeated invocations toggle between the two most recently open buffers."
(interactive)
(switch-to-buffer (other-buffer (current-buffer) 1)))
#+END_SRC
** Fold all except the current heading
With this all other subtrees in the buffer van be collapsed, leaving only the subtree at the point expanded
#+BEGIN_SRC emacs-lisp
(defun org-show-current-heading-tidily ()
(interactive) ;Inteactive
"Show next entry, keeping other entries closed."
(if (save-excursion (end-of-line) (outline-invisible-p))
(progn (org-show-entry) (show-children))
(outline-back-to-heading)
(unless (and (bolp) (org-on-heading-p))
(org-up-heading-safe)
(hide-subtree)
(error "Boundary reached"))
(org-overview)
(org-reveal t)
(org-show-entry)
(show-children)))
#+END_SRC
And it should be accessible with a quick keystroke:
#+BEGIN_SRC emacs-lisp
(global-set-key "\M-s" 'org-show-current-heading-tidily)
#+END_SRC
** Load file content as string
#+BEGIN_SRC emacs-lisp
(defun get-string-from-file (filePath)
"Return filePath's file content."
(with-temp-buffer
(insert-file-contents filePath)
(buffer-string)))
#+END_SRC
* Theming
** Main Theme
Theme source: [[https://gitlab.com/protesilaos/modus-themes][Modus Operandi]]
#+BEGIN_SRC emacs-lisp
(use-package modus-operandi-theme)
#+END_SRC
** Modeline
#+BEGIN_SRC emacs-lisp
(use-package moody
:config
(setq x-underline-at-descent-line t)
(moody-replace-mode-line-buffer-identification)
(moody-replace-vc-mode))
#+END_SRC
#+BEGIN_SRC emacs-lisp
(use-package minions
:config (minions-mode 1))
#+END_SRC
** Font
Set up the fonts that should be used by emacs.
#+BEGIN_SRC emacs-lisp
(set-face-attribute 'default nil
:family "Hack"
:height 110
:weight 'normal
:width 'normal)
(custom-theme-set-faces
'user
'(variable-pitch ((t (:family "Source Sans Pro" :height 1.0 :weight light))))
'(fixed-pitch ((t ( :family "Hack" :slant normal :weight normal :height 1.0 :width normal)))))
#+END_SRC
This sets different fonts for special blocks in org-mode. So that when ~variable-pitch~ mode is active code block are not broken.
#+BEGIN_SRC emacs-lisp
(custom-theme-set-faces
'user
'(org-block ((t (:inherit fixed-pitch))))
'(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
'(org-link ((t (:foreground "royal blue" :underline t))))
'(org-meta-line ((t (:inherit (font-lock-comment-face fixed-pitch)))))
'(org-property-value ((t (:inherit fixed-pitch))) t)
'(org-special-keyword ((t (:inherit (font-lock-comment-face fixed-pitch)))))
'(org-tag ((t (:inherit (shadow fixed-pitch) :weight bold :height 0.8))))
'(org-verbatim ((t (:inherit (shadow fixed-pitch)))))
'(org-table ((t (:inherit (shadow fixed-pitch)))))
'(org-indent ((t (:inherit (org-hide fixed-pitch))))))
#+END_SRC
* Ivy
Use Ivy to make minibuf promts better. Adds the ability to sort and filter.
** Use Ivy
#+BEGIN_SRC emacs-lisp
(use-package ivy
:init
(ivy-mode 1)
(unbind-key "S-SPC" ivy-minibuffer-map)
(setq ivy-height 30
ivy-use-virtual-buffers t
ivy-use-selectable-prompt t)
(defun swiper-at-point ()
(interactive)
(swiper (thing-at-point 'word)))
:bind (("C-x b" . ivy-switch-buffer)
("C-c C-r" . ivy-resume)
("C-c s" . swiper-at-point)
("C-s" . swiper))
:diminish)
;; ivy-rich makes Ivy look a little bit more like Helm.
(use-package ivy-rich
:after counsel
:custom
(ivy-virtual-abbreviate 'full
ivy-rich-switch-buffer-align-virtual-buffer t
ivy-rich-path-style 'abbrev)
:init
(ivy-rich-mode))
(use-package ivy-hydra)
#+END_SRC
** Smex
Sort commands by recency in ivy windows
#+BEGIN_SRC emacs-lisp
(use-package smex)
#+END_SRC
* Counsel
#+BEGIN_SRC emacs-lisp
(use-package counsel
:ensure t
:after ivy
:init
(counsel-mode 1)
:bind (("C-c ;" . counsel-M-x)
("C-c U" . counsel-unicode-char)
("C-c i" . counsel-imenu)
("C-x f" . counsel-find-file)
("C-c y" . counsel-yank-pop)
("C-c r" . counsel-recentf)
:map ivy-minibuffer-map
("C-r" . counsel-minibuffer-history))
:diminish)
#+END_SRC
* Undo Tree
Using the beauty that is undo-tree, we can easily navigate through history of a buffer.
This includes obviously going back in edit history, but also branching of end returning to previous states.
#+BEGIN_SRC emacs-lisp
(use-package undo-tree
:bind (("C-x u" . undo-tree-visualize)
("C-z" . undo-tree-undo)
("C-S-z" . undo-tree-redo))
:config
(global-undo-tree-mode +1)
(unbind-key "M-_" undo-tree-map)
:diminish)
;; Trying undo-propose, which seems to offer a better experience, as
;; undo tree is prone to losing data.
(use-package undo-propose
:disabled
:bind (("C-c _" . undo-propose)
:map undo-propose-mode-map
("<up>" . undo-only)))
#+END_SRC
With this we can use ~C-x u~ in any buffer to bring up the tree and navigate it using the arrow key.
Once in a state we agree with, just press ~q~ and we are done.
* Magit
Magit is THE go to package for using git in emacs.
#+BEGIN_SRC emacs-lisp
(use-package magit
:bind (("C-c g" . magit-status))
:diminish magit-auto-revert-mode
:diminish auto-revert-mode
:custom
(magit-remote-set-if-missing t)
(magit-diff-refine-hunk t)
:config
(magit-auto-revert-mode t)
(advice-add 'magit-refresh :before #'maybe-unset-buffer-modified)
(advice-add 'magit-commit :before #'maybe-unset-buffer-modified)
(setq magit-completing-read-function 'ivy-completing-read)
(add-to-list 'magit-no-confirm 'stage-all-changes))
(use-package libgit
:disabled
:after magit)
#+END_SRC
The ~advice-add~ entries are thereto stop magit from bugging us to save buffers when commiting and refreshing.
** Helper Functions
#+BEGIN_SRC emacs-lisp
(autoload 'diff-no-select "diff")
(defun current-buffer-matches-file-p ()
"Return t if the current buffer is identical to its associated file."
(when (and buffer-file-name (buffer-modified-p))
(diff-no-select buffer-file-name (current-buffer) nil 'noasync)
(with-current-buffer "*Diff*"
(and (search-forward-regexp "^Diff finished \(no differences\)\." (point-max) 'noerror) t))))
#+END_SRC
Clear modified bit on all unmodified buffers
#+BEGIN_SRC emacs-lisp
(defun maybe-unset-buffer-modified (&optional _)
(interactive)
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (and buffer-file-name (buffer-modified-p) (current-buffer-matches-file-p))
(set-buffer-modified-p nil)))))
#+END_SRC
Don't prompt to save unmodified buffers on exit.
#+BEGIN_SRC emacs-lisp
(advice-add 'save-buffers-kill-emacs :before #'maybe-unset-buffer-modified)
#+END_SRC
#+BEGIN_SRC emacs-lisp
(defun kill-buffer-with-prejudice (&optional _)
"Kill a buffer, eliding the save dialogue if there are no diffs."
(interactive)
(when (current-buffer-matches-file-p) (set-buffer-modified-p nil))
(kill-buffer))
#+END_SRC
* Org Mode
** Define important files
*** The Link Dump
I use a single file to dump all links I plan on viewing later.
#+BEGIN_SRC emacs-lisp
(defvar link-dump "")
(defun open-link-dump ()
(interactive)
(find-file link-dump))
#+END_SRC
** Configure org-mode
This is the main configuration for the infamous org-mode.
The most important parts are configuring key bindings to quickly access the files we have defined above.
#+BEGIN_SRC emacs-lisp
(use-package org
;; Always get this from the GNU archive.
:pin gnu
:bind (("C-c o c" . org-capture)
("C-c o l" . open-link-dump)
("C-c o s" . org-store-link)
("C-c o a" . org-agenda)
:map org-mode-map
("M-s-<return>" . org-insert-todo-heading)
("M-<return>" . org-insert-heading-respect-content)
("C-c c" . org-mode-insert-code)
("C-c a s" . org-emphasize)
("C-c a r" . org-ref)
("C-c a e" . outline-show-all)
("C-c a t" . unindent-by-four))
:hook ((org-mode . visual-line-mode)
(org-mode . variable-pitch-mode)
(org-mode . org-indent-mode))
:config
(let ((todo-path (expand-file-name "~/Notes/todo.org")))
(when (file-exists-p todo-path)
(setq org-agenda-files (list todo-path)
org-default-notes-file todo-path)))
(setq org-footnote-section ""
org-startup-with-inline-images t
org-pretty-entities t
org-indent-mode t
org-ellipsis ""
org-footnote-section nil
org-hide-leading-stars nil
org-link-file-path-type 'relative
org-image-actual-width nil ; with this image sizes can be set per image, with an attribute
)
(setcar (nthcdr 4 org-emphasis-regexp-components) 4)
(defun org-mode-insert-code ()
(interactive)
(org-emphasize ?~)))
#+END_SRC
** Set default archive location
When archiving items in org files, the default ist to crate a separate file named ~<filename>.org_archive~.
This clutters up my notes folder quite a bit, as I use a lot of separate files with thier respective archives.
All archives should be stored in a single ~.archive~ file per directory.
#+BEGIN_SRC emacs-lisp
(setq org-archive-location "./.archive::* From %s")
#+END_SRC
** Beautify org-mode
*** Icons for headline indentation
#+BEGIN_SRC emacs-lisp
(use-package org-bullets
:init (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
(setq org-bullets-bullet-list '("" "" "" "" "" ""))
#+END_SRC
*** Replace checkmark with unicode icons
#+BEGIN_SRC emacs-lisp
(use-package pretty-mode
:init (global-pretty-mode t))
(add-hook 'org-mode-hook
(lambda ()
"Beautify Org Checkbox Symbol"
(push '("[ ]" . "") prettify-symbols-alist)
(push '("[X]" . "" ) prettify-symbols-alist)
(push '("[-]" . "" ) prettify-symbols-alist)
(prettify-symbols-mode)))
#+END_SRC
We also want them in exported HTML files
#+BEGIN_SRC emacs-lisp
(setq org-html-checkbox-type 'html)
#+END_SRC
*** Strike out done ckeckbox items
#+BEGIN_SRC emacs-lisp
(defface org-checkbox-done-text
'((t (:foreground "#71696A" :strike-through t)))
"Face for the text part of a checked org-mode checkbox.")
(font-lock-add-keywords
'org-mode
`(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
1 'org-checkbox-done-text prepend))
'append)
#+END_SRC
*** Replace dash in bullet lists with unicode symbol
#+BEGIN_SRC emacs-lisp
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))
#+END_SRC
** CSS Themes for Exports
When exporting from org-mode (usually to HTML) we want to specify additional styles.
#+BEGIN_SRC emacs-lisp
(defvar org-theme-css-dir "~/.emacs.d/org-css/")
#+END_SRC
Pack some ~.css~ files into this directory. They will be available for choosing when exporting.
The folowing code will define a function to inline css into a self-contained html file.
To use it type ~M-x toggle-org-custom-inline-style~ into an org-mode buffer.
When exporting to HTML emacs will ask which css theme to use.
#+BEGIN_SRC emacs-lisp
(defun org-html-inline-style ()
(interactive)
(let ((hook 'org-export-before-parsing-hook)
(fun 'set-org-html-style))
(if (memq fun (eval hook))
(progn
(remove-hook hook fun 'buffer-local)
(message "Removed %s from %s" (symbol-name fun) (symbol-name hook)))
(add-hook hook fun nil 'buffer-local)
(message "Added %s to %s" (symbol-name fun) (symbol-name hook)))))
(defun org-theme ()
(interactive)
(let* ((cssdir org-theme-css-dir)
(css-choices (directory-files cssdir nil ".css$"))
(css (completing-read "theme: " css-choices nil t)))
(concat cssdir css)))
(defun set-org-html-style (&optional backend)
(interactive)
(when (or (null backend) (eq backend 'html))
(let ((f (or (and (boundp 'org-theme-css) org-theme-css) (org-theme))))
(if (file-exists-p f)
(progn
(set (make-local-variable 'org-theme-css) f)
(set (make-local-variable 'org-html-head)
(with-temp-buffer
(insert "<style type=\"text/css\">\n<!--/*--><![CDATA[/*><!--*/\n")
(insert-file-contents f)
(goto-char (point-max))
(insert "\n/*]]>*/-->\n</style>\n")
(buffer-string)))
(set (make-local-variable 'org-html-head-include-default-style)
nil)
(message "Set custom style from %s" f))
(message "Custom header file %s doesnt exist")))))
#+END_SRC
** Prettier Timestamps in Exports
The default timestamps look pretty unintuitive, with all the angle brackets and all. Let's make them look better.
#+BEGIN_SRC emacs-lisp
;;(add-to-list 'org-export-filter-timestamp-functions
;; #'endless/filter-timestamp)
;;(defun endless/filter-timestamp (trans back _comm)
;; (pcase back
;; ((or `jekyll `html)
;; (replace-regexp-in-string "&[lg]t;" "" trans))
;; (`latex
;; (replace-regexp-in-string "[<>]" "" trans))))
#+END_SRC
Removed for now, this somehow breaks emacs
OK, no more brackets. Now for a better formatted display.
#+BEGIN_SRC emacs-lisp
(setq-default org-display-custom-times t)
(setq org-time-stamp-custom-formats
'("<%a %d.%m.%Y>" . "<%d.%m.%y %H:%M>"))
#+END_SRC
** Templates
*** Babel
Here we set custom templates to be used for structure expansion.
These are used when we type "<" folowed by the shortcut for a template and hit "TAB".
e.g. "<s TAB" expands to ~#+BEGIN_SRC ?\n\n#+END_SRC~
**** emacs-lisp
Shortcut for creating ~emacs-lisp~ code blocks. This is used extensively in this very file.
#+BEGIN_SRC emacs-lisp
(add-to-list 'org-structure-template-alist '("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC"))
#+END_SRC
*** Capture Support Functions
First we define a function to look the subheading under which we want to file captures:
#+BEGIN_SRC emacs-lisp
(defun org-get-target-headline (&optional targets prompt)
"Prompt for a location in an org file and jump to it.
This is for promping for refile targets when doing captures.
Targets are selected from `org-refile-targets'. If TARGETS is
given it temporarily overrides `org-refile-targets'. PROMPT will
replace the default prompt message.
If CAPTURE-LOC is is given, capture to that location instead of
prompting."
(let ((org-refile-targets (or targets org-refile-targets))
(prompt (or prompt "Capture Location")))
(org-refile t nil nil prompt))
)
#+END_SRC
*** Org Capture
Here we define templates we want to use to quickly capture stuff and automatically file them away.
#+BEGIN_SRC emacs-lisp
(setq org-capture-templates
'(("l" "Link" entry (file link-dump)
"* NEW %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n%i\n")
))
#+END_SRC
** Exports using Hugo
Using ~ox-hugo~ a directory of org files can autmatically be extported to markdown files.
#+BEGIN_SRC emacs-lisp
(use-package ox-hugo
:ensure t ;Auto-install the package from Melpa (optional)
:after ox)
#+END_SRC
[[https://ox-hugo.scripter.co/][Documentation]]
* The Wiki
[[https://github.com/caiorss/org-wiki][org-wiki]] is used to create a personal desktop wiki for myself.
The advantage is that everything can be done in org-mode.
The package is not available on [[https://melpa.org/][MELPA]] as of now.
It must be installed manually:
#+BEGIN_SRC bash
(let ((url "https://raw.githubusercontent.com/caiorss/org-wiki/master/org-wiki.el"))
(with-current-buffer (url-retrieve-synchronously url)
(goto-char (point-min))
(re-search-forward "^$")
(delete-region (point) (point-min))
(kill-whole-line)
(package-install-from-buffer)))
#+END_SRC
This will ensure the package is installed and set the default wiki location
#+BEGIN_SRC emacs-lisp
(use-package org-wiki)
(setq org-wiki-location "~/org-wiki")
#+END_SRC
The backups will be stored at another location
#+BEGIN_SRC emacs-lisp
(setq org-wiki-backup-location "~/.org-wiki-backup/")
#+END_SRC
The template for new wiki pages is stored in a separate file.
This will be used to fill new pages.
#+BEGIN_SRC emacs-lisp
(setq org-wiki-template (get-string-from-file "~/.emacs.d/org-templates/wiki.org"))
#+END_SRC
** Wiki key binds
All key bindings for or wiki will start with ~C-c w~ and an additional letters for the command
#+BEGIN_SRC emacs-lisp
(bind-key "C-c w i" 'org-wiki-index) ; Go to the wiki index
(bind-key "C-c w l" 'org-wiki-insert-new) ; Link to another wiki page, will create on if it does not exist
(bind-key "C-c w e" 'org-wiki-insert-link) ; Link to an existing wiki page with helm search
(bind-key "C-c w n" 'org-wiki-new) ; Create a new page
(bind-key "C-c w s" 'org-wiki-search) ; Regex full text search
(bind-key "C-c w p" 'org-wiki-helm) ; Search pages by title
(bind-key "C-c w d" 'org-wiki-toggle-images) ; Toggle image diaplay on pages
#+END_SRC
* Deft
Deft package for very nice searching anf file creating.
#+BEGIN_SRC emacs-lisp
(use-package deft
:bind ("<f8>" . deft)
:commands (deft)
:config (setq deft-recursive t
deft-extensions '("org")
deft-default-extension "org"))
#+END_SRC
Note that the ~deft-directory~ variable has to be set before using
* Treemacs
Treemacs makes navigating folders and files much easier. This is the default config from [[https://github.com/Alexander-Miller/treemacs][the offical repository]] as a base, with slight modifications to suite my config.
#+BEGIN_SRC emacs-lisp
(use-package treemacs
:defer t
:init
(with-eval-after-load 'winum
(define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
:config
(progn
(setq treemacs-collapse-dirs (if treemacs-python-executable 3 0)
treemacs-deferred-git-apply-delay 0.5
treemacs-display-in-side-window t
treemacs-eldoc-display t
treemacs-file-event-delay 5000
treemacs-file-follow-delay 0.2
treemacs-follow-after-init t
treemacs-git-command-pipe ""
treemacs-goto-tag-strategy 'refetch-index
treemacs-indentation 2
treemacs-indentation-string " "
treemacs-is-never-other-window nil
treemacs-max-git-entries 5000
treemacs-missing-project-action 'ask
treemacs-no-png-images nil
treemacs-no-delete-other-windows t
treemacs-project-follow-cleanup nil
treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
treemacs-position 'left
treemacs-recenter-distance 0.1
treemacs-recenter-after-file-follow nil
treemacs-recenter-after-tag-follow nil
treemacs-recenter-after-project-jump 'always
treemacs-recenter-after-project-expand 'on-distance
treemacs-show-cursor nil
treemacs-show-hidden-files t
treemacs-silent-filewatch nil
treemacs-silent-refresh nil
treemacs-sorting 'alphabetic-desc
treemacs-space-between-root-nodes t
treemacs-tag-follow-cleanup t
treemacs-tag-follow-delay 1.5
treemacs-width 35)
;; The default width and height of the icons is 22 pixels. If you are
;; using a Hi-DPI display, uncomment this to double the icon size.
;;(treemacs-resize-icons 44)
(treemacs-follow-mode t)
(treemacs-filewatch-mode t)
(treemacs-fringe-indicator-mode t)
(treemacs-toggle-show-dotfiles)
(pcase (cons (not (null (executable-find "git")))
(not (null treemacs-python-executable)))
(`(t . t)
(treemacs-git-mode 'deferred))
(`(t . _)
(treemacs-git-mode 'simple))))
:bind
(:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . treemacs)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag)))
(use-package treemacs-icons-dired
:after treemacs dired
:ensure t
:config (treemacs-icons-dired-mode))
(use-package treemacs-magit
:after treemacs magit
:ensure t)
#+END_SRC
** Start with open tree
Show the tree on emacs startup
#+BEGIN_SRC emacs-lisp
(add-hook 'emacs-startup-hook 'treemacs)
#+END_SRC
* Elfeed
[[https://github.com/skeeto/elfeed][Elfeed]] is an RSS reader for emacs.
#+BEGIN_SRC emacs-lisp
(use-package elfeed
:bind ("C-x w" . 'elfeed))
#+END_SRC
** Hooks
elfeed can be extended with various hooks for ease of used
*** Auto tag youtube feeds
#+BEGIN_SRC emacs-lisp
(add-hook 'elfeed-new-entry-hook
(elfeed-make-tagger :feed-url "youtube\\.com"
:add '(video youtube)))
#+END_SRC
*** Do not spam unread tag
#+BEGIN_SRC emacs-lisp
(add-hook 'elfeed-new-entry-hook
(elfeed-make-tagger :before "2 weeks ago"
:remove 'unread))
#+END_SRC
* Programming
** Nim
These are settings and packages used for programming [[https://nim-lang.org/][nim]] in emacs
#+BEGIN_SRC emacs-lisp
(use-package nim-mode)
#+END_SRC
And an extra package to provide flycheck infos for nim
Source: [[https://github.com/ALSchwalm/flycheck-nim][Github]]
#+BEGIN_SRC emacs-lisp
(use-package flycheck-nim)
#+END_SRC
* Additional Package Imports
** All The Icons
We want to have some nice looking icons
#+BEGIN_SRC emacs-lisp
(use-package all-the-icons)
#+END_SRC
** Recentf
Show recent files in the buffer selection
#+BEGIN_SRC emacs-lisp
(use-package recentf
:init (recentf-mode t)
:config
(add-to-list 'recentf-exclude "\\.emacs.d")
(add-to-list 'recentf-exclude ".+tmp......\\.org"))
#+END_SRC
** Rainbow Delimiters
We want to have some nicely colored delimiters when reading and writing lisp code
#+BEGIN_SRC emacs-lisp
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
#+END_SRC
** Markdown Mode
#+BEGIN_SRC emacs-lisp
(use-package markdown-mode
:mode ("\\.md$" . gfm-mode)
:config
(when (executable-find "pandoc")
(setq markdown-command "pandoc -f markdown -t html")))
#+END_SRC
** Duplicate Thing
Quick bind to ~C-c u ~ to duplicate the current line
#+BEGIN_SRC emacs-lisp
(use-package duplicate-thing
:bind (("C-c u" . duplicate-thing)))
#+END_SRC
** Guide Key
Use this to get some help with key bindings
#+BEGIN_SRC emacs-lisp
(use-package guide-key
:diminish guide-key-mode
:config
(guide-key-mode t)
(setq guide-key/guide-key-sequence '("C-x v" ;; version control
"C-c a" ;; my mode-specific bindings
"C-c l" ;; line-jumping
"C-c o"
)))
#+END_SRC
** ACE Window
Small package to quickly switch tiled windows.
Use ~M-p~ to quickly switch.
#+BEGIN_SRC emacs-lisp
(use-package ace-window
:bind (("M-o" . 'ace-window)))
#+END_SRC
** htmlize
HTML Exporter for org-mode
#+BEGIN_SRC emacs-lisp
(use-package htmlize)
#+END_SRC
** which-key
This package provides a minor mode that shows a list of possible keys in the minibuffer.
After a second of inactivity the minibuffer will expand and show possible completions for the started command.
#+BEGIN_SRC emacs-lisp
(use-package which-key
:config
(which-key-mode t))
#+END_SRC
** Autocompletion
#+BEGIN_SRC emacs-lisp
(use-package company
:config
(global-company-mode))
#+END_SRC
** Transpose Frame
With the transpose-frame package windows can be rearanged in a frame without the need to close and reopen them.
#+BEGIN_SRC emacs-lisp
(use-package transpose-frame
:bind ("M-t" . transpose-frame))
#+END_SRC
* Set Variables
** General Emacs Options
#+BEGIN_SRC emacs-lisp
(setq
compilation-always-kill t ; Never prompt to kill a compilation session.
compilation-scroll-output 'first-error ; Always scroll to the bottom.
make-backup-files nil ; No backups, thanks.
auto-save-default nil ; Or autosaves. What's the difference between autosaves and backups?
create-lockfiles nil ; Emacs sure loves to put lockfiles everywhere.
default-directory "~/" ; Home sweet home.
inhibit-startup-screen t ; No need to see GNU agitprop.
kill-whole-line t ; Lets C-k delete the whole line
require-final-newline t ; Auto-insert trailing newlines.
ring-bell-function 'ignore ; Do not ding. Ever.
use-dialog-box nil ; Dialogues always go in the modeline.
initial-scratch-message nil ; SHUT UP SHUT UP SHUT UP
save-interprogram-paste-before-kill t ; preserve paste to system ring
enable-recursive-minibuffers t ; don't fucking freak out if I use the minibuffer twice
sentence-end-double-space nil ; are you fucking kidding me with this shit
confirm-kill-processes nil ; don't whine at me when I'm quitting.
mark-even-if-inactive nil ; prevent really unintuitive undo behavior
load-prefer-newer t ; load newest file version available
)
#+END_SRC
** Read environment variables from the shell
When not running on a windows system, we can use the env variables in emacs
#+BEGIN_SRC emacs-lisp
(use-package exec-path-from-shell
:if (not (eq system-type 'windows-nt))
:config
(exec-path-from-shell-initialize))
#+END_SRC
** Show the current filename in titlebar
#+BEGIN_SRC emacs-lisp
(setq frame-title-format
'((:eval user-login-name) "@" (:eval (system-name)) ": " (:eval (if (buffer-file-name)
(abbreviate-file-name (buffer-file-name))
"%b")) " [%*]"))
#+END_SRC
** Default encoding
#+BEGIN_SRC emacs-lisp
(prefer-coding-system 'utf-8)
#+END_SRC
** Shorten "yes or no" questions
#+BEGIN_SRC emacs-lisp
(defalias 'yes-or-no-p 'y-or-n-p)
#+END_SRC
** Always highlight the current line
#+BEGIN_SRC emacs-lisp
(global-hl-line-mode t)
#+END_SRC
** Always highlight matching braces
#+BEGIN_SRC emacs-lisp
(show-paren-mode t)
#+END_SRC
** Allow selection override
#+BEGIN_SRC emacs-lisp
(delete-selection-mode t)
#+END_SRC
** Behave like a normal text editor
Changed: No more CUA, ~C-c~ is used in to many places that are broken by cua-mode
#+BEGIN_SRC emacs-lisp
; (cua-mode t)
#+END_SRC
** Set cursor and indet mode
#+BEGIN_SRC emacs-lisp
(setq-default
cursor-type 'bar
indent-tabs-mode nil
cursor-in-non-selected-windows nil)
#+END_SRC
** Set default column width
#+BEGIN_SRC emacs-lisp
(set-fill-column 95)
#+END_SRC
* Hooks
** Remove trailing whitespace on file close
#+BEGIN_SRC emacs-lisp
(add-hook 'before-save-hook 'delete-trailing-whitespace)
#+END_SRC
** Elisp
Some customization for writing elisp
#+BEGIN_SRC emacs-lisp
(defun my-elisp-mode-hook ()
"My elisp customizations."
(electric-pair-mode 1)
(add-hook 'before-save-hook 'check-parens nil t)
(auto-composition-mode nil))
(add-hook 'emacs-lisp-mode-hook 'my-elisp-mode-hook)
#+END_SRC
* Global Key Bindings
#+BEGIN_SRC emacs-lisp
(bind-key "C-x k" 'kill-buffer-with-prejudice)
(bind-key "C-x C-k" 'kill-buffer-and-window)
(bind-key "C-c 5" 'query-replace-regexp) ;; stupid vestigial binding
(bind-key "M-/" 'hippie-expand)
(bind-key "C-c \\" 'align-regexp)
(bind-key "C-c m" 'compile)
(bind-key "C-c 3" 'split-right-and-enter)
(bind-key "C-c 2" 'split-below-and-enter)
(bind-key "M-p" 'switch-to-previous-buffer)
(bind-key "C-c /" 'comment-or-uncomment-region)
(bind-key "C-c x" 'ESC-prefix)
(bind-key "M-i" 'delete-indentation)
(bind-key "C-+" 'text-scale-increase)
(bind-key "C--" 'text-scale-decrease)
(bind-key "C-<" 'beginning-of-buffer)
(bind-key "C->" 'end-of-buffer)
(bind-key "C-x C-b" 'ibuffer) ;; buffer-list is not a good default
(bind-key "C-c n" 'line-number-mode)
#+END_SRC
** Unbind some default key bindings
#+BEGIN_SRC emacs-lisp
(unbind-key "C-<tab>") ;; prevent switching to tab mode randomly
(unbind-key "C-h n") ;; I have never wanted to see emacs news ever
(unbind-key "C-h C-n") ;; why on earth is it bound to two keybindings??
(unbind-key "C-x C-d") ;; list-directory is utterly useless given the existence of dired
(unbind-key "C-x C-r") ;; as is find-file-read-only
#+END_SRC
* Load Personal Information
All information about the current user should reside in the ~personal.el~ file.
This file contains personal information like name, email or other identifying information.
This file should contain definitions, that are the same on every device, but sould not be commited to a repository.
#+BEGIN_SRC emacs-lisp
(setq personal-file "~/.emacs.d/personal.el")
(load personal-file 'noerror)
#+END_SRC
* Load ~custom.el~
Load a custom file from the emacs home dir.
This file is specific to the maschine emacs runs on.
It conatins customizations and file locations that are maschine dependend.
#+BEGIN_SRC emacs-lisp
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerror)
#+END_SRC