Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
813 lines (774 sloc) 29 KB

Eivind Hjertnes’ Emacs configuration

Introduction

This is my Emacs configuration, I use it for more or less anything that require me to edit text. Everything from writing, to programming, file management and a lot of command line stuff and sometimes reading email. In August of 2019 I moved my config from a pile of well commented elisp files to this org document.

Why? Because it felt like it made more sense to have my configuration in a form where it works to give a lot of context about every single little dumb detail, to inspiration for others and to remind me why.

Settings

Personal information

(setq user-full-name "Eivind Hjertnes"
      user-mail-address "me@hjertnes.me")

Package manager

One of the first things I do is to configure the Emacs package system to use all the package sources I know of, and to install use-package, request and org-plus-contrib; and then load use-package.

Use-package will be used to load, install and configure more or less all other pakcages. Request are installed here because I use it in some of my interactive functions. And I install org-contrib-plus here because I either have to do this or to have nested use-packages, and I’m doing the lesser evil.

(require 'package)
(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/") 
			 ("marmalade" . "http://marmalade-repo.org/packages/") 
			 ("org" . "https://orgmode.org/elpa/") 
			 ("melpa" . "http://melpa.org/packages/")))
(package-initialize)
(unless package-archive-contents (package-refresh-contents))
(dolist (package 
	 '(use-package
	    org-plus-contrib
	    request)) 
  (unless (package-installed-p package) 
    (package-install package)))
(eval-when-compile 
  (require 'use-package))

Helper functions

Various helper functions I use a few different places in my setup. Most of them do stuff like reading passwords from auth-info, predicates for figuring out what kind of system it is or isn’t and a few date related functions I use in my yasnippets

(defun get-password (name) 
  (let* ((results (auth-source-search :host name)) 
	 (result (car results)) 
	 (secrets (plist-get result 
			     :secret)) 
	 (secret (first (aref (aref secrets 2) 0)))) secret)) 
;; Check if current system is windows
(defun is-windows () 
  (eq system-type 'windows-nt))
;; Check if current system is not windows
(defun is-not-windows () 
  (not (eq system-type 'windows-nt)))
(defun is-mac () 
  (eq system-type 'darwin))
(defun is-linux () 
  (eq system-type 'gnu/linux))
(defvar current-date-time-format "%a %b %d %H:%M:%S %Z %Y" 
  "Format of date to insert with `insert-current-date-time' func
See help of `format-time-string' for possible replacements")

(defun get-url()
  (format-time-string "/%Y/%m/%d/"))
(defun get-datestring()
  (format-time-string "%Y-%m-%dT%T"))
(defun get-timestring()
  ((lambda (x) 
		     (concat (substring x 0 3) ":" (substring x 3 5))) 
		   (format-time-string "%z")))

Interactive functions

Interactive functions that I use from time to time to do stuff that isn’t as easy as I like out of the box.

Post to Micro.blog

Micro.blog is my “social” media of choice. It is a tiny network tied together with blogs and rss feeds. This is a tiny function I use to post from emacs.

(require 'request)
(defun microblog () 
  "Post without title." 
  (interactive) 
  (if (yes-or-no-p "Are you sure you want to post this? ")
      (progn
      (switch-to-buffer (org-md-export-as-markdown))
      (request "https://micro.blog/micropub" 
	       :type "POST" 
	       :data `(("h"."entry")
		       ("content" .
			,(buffer-substring-no-properties 
			  (point-min) 
			  (point-max))))
	       :headers `(("Authorization" . ,(format "Bearer %s" (get-password "microblog"))))
	       :success (cl-function (lambda 
				       (&key 
					data
					&allow-other-keys)
				       (message "Success")))))))

New Empty Buffer

Stole this one from http://ergoemacs.org/emacs/emacs_new_empty_buffer.html. It is a small function that let me create a new “scratch” buffer.

(defun new-empty-buffer () 
  "Create a new empty buffer." 
  (interactive) 
  (let (($buf (generate-new-buffer "untitled"))) 
    (switch-to-buffer $buf) 
    (funcall initial-major-mode) 
    (setq buffer-offer-save t)
    $buf))

Save all

Not soemthing I use a lot, but I do use it when I have search and replaced a lot of files, and just want to save it all.

(defun save-all () 
  (interactive) 
  (save-some-buffers t))

Eshell New

Eshell doesn’t have a “give me another shell” interactive function for some weird reason. This function let me create a new one.

(defun eshell-new()
  "Open a new instance of eshell."
  (interactive)
  (eshell 'N))

GC

I keep my GC limit to 8GB. It might seem extreme, but it works fine for me on my systems. It never gets close to that on my OS X or Linux systems, and memoery use is always ridicolus on my Windows work laptop.

(setq gc-cons-threshold 8000000000)

Undo limit

This sets a very high limit on how much stuff emacs keeps in the kill ring. I hate loosing stuff from Copy Paste fuckups. Like with GC, this could probably be lower, but I don’t bother with doing so before I have a real reason for it.

(setq undo-limit 1000000000 undo-strong-limit 1000000000)

Default Mode

These two settings forces emacs to use text-mode as its default mode, used when emacs can’t figure out what mode to use. It is probasbly not needed to use both of those settings.

(setq initial-major-mode (quote text-mode))
(setq-default major-mode 'text-mode)

Indent

Sets emacs to not use tab as ident, and sets various two spaces per tab variables. And I enable electric ident mode which will ident a line to the previous one when you hit RET.

(setq tab-with 2 indent-tabs-mode nil js-indent-level 2)
(electric-indent-mode +1)

OS X stuff

Just some settings that make Emacs better under OS X

Make it prettier

(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist '(ns-appearance . dark))

Use the native full screen

(setq ns-use-native-fullscreen t)

Make Emacs ignore the right command and option

This setting is really useful if you like me sometimes need to type characters that are under a option combo on OS X. This setting tells emacs to not do anything with the right option and command.

(when (eq system-type 'darwin)
  (setq mac-right-option-modifier 'none mac-right-command-modifier 'none))

Get path from shell

Paths can be a little bit weird if you start emacs as an App on OS X. This package fixes it.

(use-package 
  exec-path-from-shell 
  :ensure t 
  :if (is-not-windows) 
  :config (exec-path-from-shell-initialize))

Backup files etc

The default setup for emacs creates various lock and backup files and some auto-save stuff. This diables all of that.

(setq create-lockfiles nil make-backup-files nil auto-save-default nil)

Better SSH for TRAMP

This makes using TRAMP over SSH better, don’t remember the details.

(setq tramp-default-method "sshx")

Syntax for Re-builder

Re-builder is this awesome emacs feature where you can create a regexp search and replace and see where it will match. This sets the default regexp syntax to a less weird one. The default requires a ridicolus amount of backslashes.

(setq reb-re-syntax 'string)

X11 Clipboard integration

Makes sure emacs and the X11 clipboard work better together.

(setq select-enable-clipboard t)

Server mode

Server modes enable you to use emacs client. Great if you want to send files to be edited on a running emacs instance from the commandline.

(server-mode +1)

Column numbers

Showing column numbers and line numbers in the mode line

(column-number-mode +1)

Autosave & autoload

These two modes will make emacs auto save files, and load them from disk if the file changes.

(global-auto-revert-mode +1)
(auto-save-visited-mode +1)

Pairs

Electric pair mode will insert a matching symbol for pairs like ()[] etc. And smart parens is a superior way to working with them.

(electric-pair-mode +1)
(use-package 
  smartparens 
  :ensure t 
  :config (progn 
	    (require 'smartparens-config) 
	    (smartparens-global-mode t)
	    ;; keybinding management
	    (define-key smartparens-mode-map (kbd "C-M-f") 'sp-forward-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-b") 'sp-backward-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-d") 'sp-down-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-a") 'sp-backward-down-sexp) 
	    (define-key smartparens-mode-map (kbd "C-S-d") 'sp-beginning-of-sexp) 
	    (define-key smartparens-mode-map (kbd "C-S-a") 'sp-end-of-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-e") 'sp-up-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-u") 'sp-backward-up-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-t") 'sp-transpose-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-n") 'sp-forward-hybrid-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-p") 'sp-backward-hybrid-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-k") 'sp-kill-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-w") 'sp-copy-sexp) 
	    (define-key smartparens-mode-map (kbd "M-<delete>") 'sp-unwrap-sexp) 
	    (define-key smartparens-mode-map (kbd "M-<backspace>") 'sp-backward-unwrap-sexp) 
	    (define-key smartparens-mode-map (kbd "C-<right>") 'sp-forward-slurp-sexp) 
	    (define-key smartparens-mode-map (kbd "C-<left>") 'sp-forward-barf-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-<left>") 'sp-backward-slurp-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-<right>") 'sp-backward-barf-sexp) 
	    (define-key smartparens-mode-map (kbd "M-D") 'sp-splice-sexp) 
	    (define-key smartparens-mode-map (kbd "C-M-<delete>") 'sp-splice-sexp-killing-forward) 
	    (define-key smartparens-mode-map (kbd "C-M-<backspace>")
	      'sp-splice-sexp-killing-backward) 
	    (define-key smartparens-mode-map (kbd "C-S-<backspace>") 'sp-splice-sexp-killing-around) 
	    (define-key smartparens-mode-map (kbd "C-]") 'sp-select-next-thing-exchange) 
	    (define-key smartparens-mode-map (kbd "C-<left_bracket>") 'sp-select-previous-thing) 
	    (define-key smartparens-mode-map (kbd "C-M-]") 'sp-select-next-thing) 
	    (define-key smartparens-mode-map (kbd "M-F") 'sp-forward-symbol) 
	    (define-key smartparens-mode-map (kbd "M-B") 'sp-backward-symbol) 
	    (define-key smartparens-mode-map (kbd "C-\"") 'sp-change-inner) 
	    (define-key smartparens-mode-map (kbd "M-i") 'sp-change-enclosing) 
	    (bind-key "C-c f" (lambda () 
				(interactive) 
				(sp-beginning-of-sexp 2)) smartparens-mode-map) 
	    (bind-key "C-c b" (lambda () 
				(interactive) 
				(sp-beginning-of-sexp -2)) smartparens-mode-map) 
	    (bind-key "H-t" 'sp-prefix-tag-object smartparens-mode-map) 
	    (bind-key "H-p" 'sp-prefix-pair-object smartparens-mode-map) 
	    (bind-key "H-y" 'sp-prefix-symbol-object smartparens-mode-map) 
	    (bind-key "H-h" 'sp-highlight-current-sexp smartparens-mode-map) 
	    (bind-key "H-e" 'sp-prefix-save-excursion smartparens-mode-map) 
	    (bind-key "H-s c" 'sp-convolute-sexp smartparens-mode-map) 
	    (bind-key "H-s a" 'sp-absorb-sexp smartparens-mode-map) 
	    (bind-key "H-s e" 'sp-emit-sexp smartparens-mode-map) 
	    (bind-key "H-s p" 'sp-add-to-previous-sexp smartparens-mode-map) 
	    (bind-key "H-s n" 'sp-add-to-next-sexp smartparens-mode-map) 
	    (bind-key "H-s j" 'sp-join-sexp smartparens-mode-map) 
	    (bind-key "H-s s" 'sp-split-sexp smartparens-mode-map) 
	    (bind-key "H-s r" 'sp-rewrap-sexp smartparens-mode-map) 
	    (defvar hyp-s-x-map) 
	    (define-prefix-command 'hyp-s-x-map) 
	    (bind-key "H-s x" hyp-s-x-map smartparens-mode-map) 
	    (bind-key "H-s x x" 'sp-extract-before-sexp smartparens-mode-map) 
	    (bind-key "H-s x a" 'sp-extract-after-sexp smartparens-mode-map) 
	    (bind-key "H-s x s" 'sp-swap-enclosing-sexp smartparens-mode-map) 
	    (bind-key "C-x C-t" 'sp-transpose-hybrid-sexp smartparens-mode-map) 
	    (bind-key ";" 'sp-comment emacs-lisp-mode-map) 
	    (bind-key [remap c-electric-backspace] 'sp-backward-delete-char
		      smartparens-strict-mode-map)))

OX Hugo

A fantastic package that can turn a org document to markdown files that blog systems that hugo can use to generate a website.

(use-package 
  ox-hugo 
  :ensure t 
  :init (setq org-hugo-front-matter-format 'yaml) 
  :after ox)
(use-package 
  ox-json
  :ensure t )

Highlight TODO comments

This highlights todo comments in buffers. Really useful if you like me always want to deal with them if possible.

(use-package 
  hl-todo 
  :ensure t
  :config (hl-todo-mode +1))

Theme

Loads my theme, currently solarized-dark

(use-package
  solarized-theme
   :config (load-theme 'solarized-dark t)
  :ensure t)

Flycheck

Flycheck is this awesome package that everything works with. It an show you warnings and errors in your code.

(use-package 
  flycheck 
  :ensure t 
  :init (setq flycheck-disabled-checkers '(javascript-standard javascript-jshint)) 
  :config(global-flycheck-mode))

Projectile

Projectile makes it a lot easier to switch between projects in Emacs. It keeps me a LOT saner at work.

(use-package 
  projectile 
  :ensure t 
  :init (setq projectile-indexing-method 'alien projectile-completion-system 'ivy projectile-project-search-path '("~/Code/")) 
  :config (progn (projectile-mode) 
		 (define-key projectile-mode-map (kbd "M-p") 'projectile-command-map)))

Company

A better autocomplete system than the built in one. Most major modes for emacs that have some kind of auto complete also integrates with company.

(use-package 
  company 
  :ensure t 
  :init (setq company-dabbrev-downcase 0 company-idle-delay 0) 
  :config (progn(company-mode +1) 
		(global-company-mode +1)))

Rainbow

These two packages makes sure that symbols like [] {} etc and keywords (variables, functions etc) get different colours. Makes it a lot easier and faster to read and work with code.

(use-package 
  rainbow-delimiters
  :ensure t 
  :config (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
(use-package 
  rainbow-identifiers 
  :ensure t 
  :config (add-hook 'prog-mode-hook 'rainbow-identifiers-mode))

Ivy

Ivy provide a lot of the same functionality that Helm has, just that I like it better.

Smex

This package provide history for the M-x command, great if you need to run the same thing multiple times or re-do the thing you did 5 commands ago.

(use-package 
  smex 
  :ensure t 
  :config (smex-initialize))

Aggressive ident

(use-package aggressive-indent :ensure t :config (global-aggressive-indent-mode 1))

Hl indent

(use-package highlight-indentation :ensure t :config (progn (highlight-indentation-mode) (highlight-indentation-current-column-mode)))

Restart Emacs

(use-package restart-emacs :ensure t)

Multiple cursors

(use-package multiple-cursors :ensure t)

Pkg-info

(use-package pkg-info :ensure t)

Cousel

This setups up Ivy and maps it to keyboard shortcuts so that I use Ivy or Counsel for stuff like M-x, selecting buffers, saarching etc .

(use-package 
  counsel 
  :ensure t 
  :config (progn (ivy-mode 1) (counsel-mode 1)
		 (global-set-key (kbd "C-x C-b") 'ivy-switch-buffer) 
		 (global-set-key (kbd "C-s") 'swiper) 
		 (global-set-key (kbd "M-x") 'counsel-M-x) 
		 (global-set-key (kbd "C-x C-f") 'counsel-find-file) 
		 (global-set-key (kbd "<f1> f") 'counsel-describe-function) 
		 (global-set-key (kbd "<f1> v") 'counsel-describe-variable) 
		 (global-set-key (kbd "<f1> l") 'counsel-find-library) 
		 (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol) 
		 (global-set-key (kbd "<f2> u") 'counsel-unicode-char)) 
  :init (setq  ivy-initial-inputs-alist nil ivy-use-virtual-buffers t ivy-count-format "(%d/d)"))

Counsel Projectile

This package enables projectile commands using Ivy stuff. A lot nicer than the default.

(use-package 
  counsel-projectile 
  :ensure t 
  :after (counsel projectile) 
  :config (counsel-projectile-mode +1))

Counsel Tramp

This package enables tramp commands using Ivy stuff. A lot nicer than the default.

(use-package 
  counsel-tramp 
  :ensure t 
  :after (counsel) 
  :init (setq tramp-default-method "ssh") 
  :config (define-key global-map (kbd "C-c s") 'counsel-tramp))

Yasnippet

This package enables you do write snippests for stuff you type over and over and over. I don’t use it a lot, but more than worth it.

(use-package yasnippet
  :ensure t
  :init (setq  yas-snippet-dirs '("~/.emacs.d/snippets"))
  :config
  (yas-global-mode 1)
  :bind (("M-s M-s" . yas-insert-snippet)("C-c y" . yas-expand)("C-c p" . yas-prev-field)("C-c n" . yas-next-field)))

Avy

(use-package avy :ensure t :config (avy-setup-default) (global-set-key (kbd "C-:") 'avy-goto-char))

Ace

These packages are awesome. Ace Jump is this voodoo thing that let you move really fast; M-x ace-jump and then hit u. It will now show you all places “u” is replaced with a-z” if you hit e you’ll jump to the fifth occourance. While ace-window makes it A LOT easier to manage windows.

;; TODO fix these keybindings
(use-package 
  ace-jump-mode 
  :ensure t 
  :bind (("C-c SPC" . ace-jump-mode) 
	 ("C-c C-u SPC" . ace-jump-char-mode) 
	 ("C-c C-u C-u SPC" . ace-jump-line-mode)))
;; ace-window: makes it easier to manage windows in emacs
(use-package 
  ace-window 
  :ensure t 
  :init (setq aw-dispatch-always t) 
  :config (global-set-key (kbd "M-o") 'ace-window))

Eshell

Enables Z in eshell. It is this machine learning thing that learn from the directorys to go to and let you type less to go into them.

(use-package eshell-z :ensure t :config (add-hook 'eshell-mode-hook (defun my-eshell-mode-hook ()(require 'eshell-z))))

Search

An awesome to search in a directory.

(use-package deadgrep :ensure t :bind (("<f5>". deadgrep)))

Undo

Undo-tree makes undo works a little bit more like you expect, and it also has this awesome command to interactivly move through the history. And browse kill ring let you browse the current kill ring

(use-package undo-tree :ensure t :config (global-undo-tree-mode))
(use-package browse-kill-ring :ensure t)

Feed

This is my current RSS / Atom feed reader of choice. I like it a lot, all my feeds are stored in a org file. And it is easy to manage them, and process new items. It takes me way less time to go through them all and send it to Firefox than my previous setup.

(use-package elfeed
  :init (add-hook 'elfeed-show-mode-hook (lambda()
(local-set-key "\C-n" 'elfeed-show-next)
(local-set-key "\C-p" 'elfeed-show-prev)
))
  :ensure t)
(use-package elfeed-org :ensure t :config (elfeed-org) :after (elfeed))

UI

Changes that are first and foremost UI changes

Font

I use Source Code Pro with different since on my different systems

(set-face-attribute 'default nil 
		    :family "Source Code Pro" 
		    :height (cond ((is-windows) 100)
				  ((is-linux) 100) 
				  ((is-mac) 140)) 
		    :weight 'normal 
		    :width 'normal)

Mininmal UI

No welcome screen on startup and no toolbar or scroll bars.

(setq inhibit-startup-message t initial-scratch-message nil)
(scroll-bar-mode -1)
(tool-bar-mode -1)

Wrap lines

I prefer my lines to wrap.

(global-visual-line-mode 1)

Highlight matching parens

Making emacs highlighting the other side of a pair makes coding a lot easier.

(show-paren-mode 1)

Highlight Search

Enables you to highlight everything matching a search in the current buffer with a speicifc color

(global-hi-lock-mode +1)

Indent Guide

Shows markers for ident levels

(use-package 
  indent-guide 
  :ensure t 
  :config (indent-guide-global-mode))

Line numbers

Shows line numbers on the left of each buffer.

(global-linum-mode 1)

Highlight current line

Highlight the current line. All of it.

(global-hl-line-mode 1)

Window divider

Adds a divider between windows, that you can use to resize them.

(window-divider-mode 1)

Langauges

Haskell

Enables Haskell support, but I haven’t tested it yet.

(use-package intero :ensure t :config (add-hook 'haskell-mode-hook 'intero-mode))

TaskPaper

TaskPaper support.

(use-package 
  taskpaper-mode 
  :ensure t)

Feature files

Feature file, Cucumber, karate, call them what you will.

(use-package 
  feature-mode 
  :ensure t 
  :config (setq feature-default-langauge "fi"))

HTML

HTML support

(use-package 
  web-mode 
  :ensure)

JSON

JSON support

(use-package 
  json-mode 
  :ensure)

JavaScript

JS support. Not perfect, VS Code is probably better, but it works.

(use-package 
  js2-mode 
  :ensure t 
  :mode "\\.js\\'" 
  :interpreter "node" 
  :init (setq-default js2-concat-multiline-strings 'eol) 
  (setq-default js2-global-externs '("module" "require" "setTimeout" "clearTimeout" "setInterval"
				     "clearInterval" "location" "__dirname" "console" "JSON"
				     "window" "process" "fetch")) 
  (setq-default js2-strict-inconsistent-return-warning nil) 
  :config (use-package 
	    prettier-js 
	    :ensure t) 
  (use-package 
    rjsx-mode 
    :ensure t 
    :mode "\\.js\\'" 
    :magic ("import React" . rjsx-mode)))

C#

C# support. It works and is pretty awesome. Use it most of the time

(defun csharp-config () 
  (add-to-list 'company-backends #'company-omnisharp) 
  (add-hook 'csharp-mode-hook (lambda() 
				(omnisharp-mode) 
				(company-mode) 
				(flycheck-mode) 
				(setq indent-tabs-mode nil company-idle-delay .1
				      c-syntactic-indentation t c-basic-offset 4 truncate-lines t
				      tab-width 4) 
				(local-set-key (kbd "C-c r r")
					       'omnisharp-run-code-action-refactoring) 
				(local-set-key (kbd "C-c C-c") 'recompile))))
(use-package 
  omnisharp 
  :ensure t 
  :hook ((before-save . omnisharp-code-format-entire-file))
  :init (setq omnisharp-server-executable-path(cond((is-windows)
						    "C:\\Bin\\omnisharp-roslyn\\OmniSharp.exe") 
						   ((is-mac)  "~/bin/omnisharp") 
						   ((is-linux)
						    "/opt/omnisharp-roslyn/OmniSharp.exe"))) 
  :config (csharp-config))

Docker

Support for Dockerfiles and docker-compose files

(use-package 
  dockerfile-mode 
  :ensure t 
  :config (add-to-list 'auto-mode-alist '("Dockerfile\\'" . dockerfile-mode)))
;; Docker-compose files
(use-package 
  docker-compose-mode 
  :ensure t)

Org

Org support

(use-package 
  org 
  :ensure t
  :init (setq org-export-with-toc nil org-descriptive-links nil)
  :pin org)
(use-package org-journal :ensure t :init (setq org-journal-dir "~/txt/journal/" org-journal-file-format "%Y-%m-%d" org-journal-date-prefix "#+TITLE: " org-journal-date-format "%Y-%m-%d" org-journal-time-prefix "* " org-journal-time-format "%H:%M:%S") :when (is-not-windows))

Clojure

Clojure support.

(use-package 
  clojure-mode 
  :ensure t)
;; Clojure Repl integration and much more
(use-package 
  cider 
  :ensure t 
  :config (progn (add-hook 'cider-repl-mode-hook #'cider-company-enable-fuzzy-completion) 
		 (add-hook 'cider-mode-hook #'cider-company-enable-fuzzy-completion) 
		 (add-hook 'after-save-hook (lambda() 
					      (when (eq major-mode 'clojure-mode) 
						(cider-load-buffer
						 ))))))

Markdown

markdown support

(use-package 
  markdown-mode 
  :ensure t 
  :commands (markdown-mode gfm-mode) 
  :mode (("README\\.md\\'" . gfm-mode) 
	 ("\\.txt\\'" . markdown-mode) 
	 ("\\.md\\'" . markdown-mode) 
	 ("\\.markdown\\'" . markdown-mode))
  :init (setq markdown-command "multimarkdown"))

TOML

TOML, the Hugo syntax.

(use-package toml-mode :ensure t)

Elisp

Some utils for elisp.

(use-package 
  package-lint 
  :ensure t)
(use-package 
  elisp-format 
  :ensure t)

Apps

Email

My Mu4e setup

(use-package mu4e
  :when (is-linux)
  :init (setq
	 mu4e-maildir (expand-file-name "~/Mail")
 mu4e-drafts-folder "/Drafts"
 mu4e-refile-folder "/Archive"
 mu4e-sent-folder   "/Sent Items"
 mu4e-trash-folder  "/Trash"
 mu4e-get-mail-command "mbsync -a"
 user-mail-address "me@hjertnes.me"
 user-full-name  "Eivind Hjertnes"
 smtpmail-default-smtp-server "smtp.fastmail.com"
 smtpmail-smtp-server "smtp.fastmail.com"
 smtpmail-smtp-service 587
 mu4e-bookmarks
 `(
   ("flag:unread AND NOT flag:trashed" "Unread messages" ?u)
   ("maildir:/INBOX" "Inbox" ?i)
   )))

File explorer

Treemacs is the only good nerd tree style file explorer for emacs. It is like Neotree only that it works better.

(use-package 
  treemacs 
  :ensure t 
  :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 (executable-find "python3") 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-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-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-modep t) 
	    (treemacs-filewatch-mode t) 
	    (treemacs-fringe-indicator-mode t) 
	    (pcase (cons (not (null (executable-find "git"))) 
			 (not (null (executable-find "python3")))) 
	      (`(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-projectile 
  :after treemacs 
  projectile 
  :ensure t)

(use-package 
  treemacs-icons-dired 
  :after treemacs 
  dired 
  :ensure t 
  :config (treemacs-icons-dired-mode))

(use-package 
  treemacs-magit 
  :after treemacs 
  magit 
  :ensure t)

Magit

My favourite git client

(use-package 
  magit 
  :init (setq magit-completing-read-function 'ivy-completing-read) 
  :ensure t)

Web browser

I’m testing this out now and then, but not really good enough to be useful.

(use-package w3m :ensure t :when (is-not-windows))
You can’t perform that action at this time.