diff --git a/.gitignore b/.gitignore index 5496de3..fd4c7d3 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ icons transient .cache server -setup-emacs.el *.desktop *.lock personal.el +README.el diff --git a/README.org b/README.org index efedb72..a5dc0a3 100644 --- a/README.org +++ b/README.org @@ -1,23 +1,895 @@ -#+OPTIONS: toc:nil -* Emacs Configuration -This repository contains my configuration files for the emacs editor. -** About this config -This configuration uses a literate programming style to make maintaining an emacs configuration easier. -The main configuration is performed in the ~setup-emacs.org~ file. -** Using this config -To use this configuration, all you need to do is save this respoitory as your ~.emacs.d~ folder and restart emacs. -#+BEGIN_SRC bash - git clone "https://github.com/luxick/emacs-config.git" ~/.emacs.d +#+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 + +* 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/setup-emacs.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 + +* Theming +** Main Theme +#+BEGIN_SRC emacs-lisp + (use-package doom-themes) + + ;; Global settings (defaults) + (setq doom-themes-enable-bold t ; if nil, bold is universally disabled + doom-themes-enable-italic t) ; if nil, italics is universally disabled + + ;; Load the theme (doom-one, doom-molokai, etc); keep in mind that each theme + ;; may have their own settings. + (load-theme 'doom-one-light t) + + ;; Enable flashing mode-line on errors + (doom-themes-visual-bell-config) + + ;; Corrects (and improves) org-mode's native fontification. + (doom-themes-org-config) +#+END_SRC + +** Modeline +#+BEGIN_SRC emacs-lisp + (use-package doom-modeline + :ensure t + :hook (after-init . doom-modeline-mode)) +#+END_SRC + +*** Minions Menu +Add a menu to the modeline to access all minor modes. +#+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 + ("" . 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-" . org-insert-todo-heading) + ("M-" . 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 ~.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 "\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. "" . 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 + +* 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 +#+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-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 +#+END_SRC + +** Unbind some default key bindings +#+BEGIN_SRC emacs-lisp + (unbind-key "C-") ;; 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 -*** Customization -The configurations contains some settings specific to my workflow/preferences. Those should be changed before starting to use emacs. -**** Org Folder Locations -I have a folder named ~Notes~ in my home dir which serves as a central spot for all my org related files. -This is reflected in serval variables in ~setup-emacs.org~. If this is not what you want you will have to search for all occurences of the folder name and replace them by hand. -**** Personal Information -All personal information, that emacs should use (username, e-mail address, etc.) should be written into the ~personal.el~ file -** Notable Features -*** Inlining CSS into Org HTML exports -The ~org-css~ folder contains some CSS files for better looking HTML org exports. -Before exporting ~M-x org-html-inline-syle~ can be used to enable inlining CSS into the exported HTML file. -This results in a single, self contained HTML file with the desired look. diff --git a/init.el b/init.el index a1047b6..9bf916a 100644 --- a/init.el +++ b/init.el @@ -6,6 +6,6 @@ (require 'org) (org-babel-load-file - (expand-file-name (concat user-emacs-directory "setup-emacs.org"))) + (expand-file-name (concat user-emacs-directory "README.org"))) (provide 'init) diff --git a/setup-emacs.org b/setup-emacs.org deleted file mode 100644 index a5dc0a3..0000000 --- a/setup-emacs.org +++ /dev/null @@ -1,895 +0,0 @@ -#+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 - -* 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/setup-emacs.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 - -* Theming -** Main Theme -#+BEGIN_SRC emacs-lisp - (use-package doom-themes) - - ;; Global settings (defaults) - (setq doom-themes-enable-bold t ; if nil, bold is universally disabled - doom-themes-enable-italic t) ; if nil, italics is universally disabled - - ;; Load the theme (doom-one, doom-molokai, etc); keep in mind that each theme - ;; may have their own settings. - (load-theme 'doom-one-light t) - - ;; Enable flashing mode-line on errors - (doom-themes-visual-bell-config) - - ;; Corrects (and improves) org-mode's native fontification. - (doom-themes-org-config) -#+END_SRC - -** Modeline -#+BEGIN_SRC emacs-lisp - (use-package doom-modeline - :ensure t - :hook (after-init . doom-modeline-mode)) -#+END_SRC - -*** Minions Menu -Add a menu to the modeline to access all minor modes. -#+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 - ("" . 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-" . org-insert-todo-heading) - ("M-" . 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 ~.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 "\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. "" . 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 - -* 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 -#+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-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 -#+END_SRC - -** Unbind some default key bindings -#+BEGIN_SRC emacs-lisp - (unbind-key "C-") ;; 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