   (unless (require 'use-package nil 'noerror)
     (package-install 'use-package)
     (require 'use-package)))
-(setq use-package-always-ensure t
-      use-package-always-defer t)
-
-(use-package powerline
-  :demand)
-(use-package powerline-evil
-  :after powerline)
+(setq use-package-always-ensure t)
+
+;;; Start of use-package stanzas
+;; I will somewhat keep to a system of placing options and necessary
+;; hooks in the :init and :config fields, but defining most useful
+;; keybindings further down this file.
+;; :bind is easily replaced with a :command and map in init, which is
+;; also more in line with how the command+hook works.
+
+(use-package powerline)
+(use-package powerline-evil)
 (use-package moe-theme
-  :after powerline-evil
-  :config (progn
-            (moe-dark)
-            (powerline-moe-theme)
-            (powerline-evil-center-color-theme)))
+  :config
+  (progn
+    (moe-dark)
+    (powerline-moe-theme)
+    (powerline-evil-center-color-theme)))
+
+;; System for defining keys easily, relies on evil since i use that.
+(eval-when-compile
+  (defun pair-list (l)
+    "Pair elements in even list L."
+    (if l
+        (cons (list (car l) (cadr l))
+              (pair-list (cddr l)))
+      nil))
+  (defun add-map (map pair)
+    "Create a 'define-key to MAP with mapping PAIR."
+    (list 'define-key map (list 'kbd (car pair)) (cadr pair)))
+  (defun add-map-list (map l)
+    "Perform add-map using MAP on all of list L."
+    (mapcar (lambda (x) (add-map map x)) (pair-list l)))
+  (defmacro imap (&rest l)
+    "Map the bindings of L with 'evil-insert-state-map."
+    `(progn ,@(add-map-list 'evil-insert-state-map l)))
+  (defmacro nmap (&rest l)
+    "Map the bindings of L with 'evil-normal-state-map."
+    `(progn ,@(add-map-list 'evil-normal-state-map l)))
+  (defmacro amap (&rest l)
+    "Map the bindings of L with all the maps."
+    `(progn ,@(add-map-list 'evil-normal-state-map l)
+            ,@(add-map-list 'evil-insert-state-map l)
+            ,@(add-map-list 'evil-emacs-state-map l))))
+
+(use-package evil
+  :config
+  (progn
+    (evil-define-command ERC ()
+      "edit rc"
+      (find-file "~/.emacs"))
+    (evil-mode 1)))
+
+(use-package evil-matchit
+  :config (global-evil-matchit-mode))
+
+(use-package which-key
+  :config
+  (progn
+    (which-key-mode)
+    (setq which-key-idle-delay 0.2))
+  :diminish which-key-mode)
+
+(use-package hydra)
 
 (use-package undo-tree
-  :demand
   :config (global-undo-tree-mode)
   :diminish undo-tree-mode)
 
-(use-package evil
-  :demand
+(use-package smartparens
   :config (progn
-            (evil-define-command ERC ()
-              "edit rc"
-              (find-file "~/.emacs"))
-            (evil-mode 1)))
-
-(use-package evil-matchit
-  :after evil
-  :config (global-evil-matchit-mode))
-
+            (require 'smartparens-config)
+            (smartparens-global-mode)))
+
+(use-package rainbow-delimiters
+  :init (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
+
+(use-package magit)
+
+(use-package flx)
+
+(use-package ivy
+  :config
+  (progn
+    (ivy-mode t)
+    (setq ivy-use-virtual-buffers t)
+    (setq ivy-initial-inputs-alist '())
+    (amap "<f2>" 'ivy-switch-buffer))
+  :diminish ivy-mode)
+
+(use-package counsel
+  :config
+  (progn
+    (counsel-mode 1)
+    (setq ivy-re-builders-alist '((swiper . ivy--regex-plus) (t . ivy--regex-fuzzy)))
+    (nmap "<f3>" 'counsel-find-file))
+  :diminish counsel-mode)
+
+(use-package swiper)
+
+(use-package recentf
+  :config
+  (progn
+    (recentf-mode 1)
+    (setq recentf-max-saved-items 512)))
+
+(use-package company
+  :init (defvar company-idle-delay 0.1)
+  :config (global-company-mode)
+  :diminish company-mode)
+
+(use-package flycheck
+  :config (global-flycheck-mode))
+
+(use-package yasnippet
+  :config
+  (progn
+    (setq-default yas-snippet-dirs '("~/.emacs.d/snippets"))
+    (yas-global-mode))
+  :diminish yas-minor-mode)
+
+;; Org
+(use-package org
+  :defer                                ;In default alist
+  :init
+  (progn
+    (defvar org-startup-indented t)
+    (defvar org-src-fontify-natively t)
+    (defvar org-confirm-babel-evaluate nil))
+  :config
+  (org-babel-do-load-languages
+   'org-babel-load-languages
+   '((C . t) (haskell . t) (emacs-lisp . t) (latex . t) (python . t))))
+
+;; Lisp
 (use-package slime
+  :defer
   :init (defvar inferior-lisp-program "/usr/bin/sbcl")
   :config (slime-setup))
 
+;; Python
 (use-package elpy
-  :commands elpy-enable
+  :defer
   :init (add-hook 'python-mode-hook 'elpy-enable))
 
-(use-package paredit
-  :commands enable-paredit-mode
-  :init (progn
-          (add-hook 'emacs-lisp-mode-hook                  'enable-paredit-mode)
-          (add-hook 'eval-expression-minibuffer-setup-hook 'enable-paredit-mode)
-          (add-hook 'ielm-mode-hook                        'enable-paredit-mode)
-          (add-hook 'lisp-mode-hook                        'enable-paredit-mode)
-          (add-hook 'lisp-interaction-mode-hook            'enable-paredit-mode)
-          (add-hook 'scheme-mode-hook                      'enable-paredit-mode)))
-
-(use-package magit
-  :bind ("C-x g" . magit-status))
-
-(use-package org
-  :init (progn
-          (defvar org-startup-indented t)
-          (defvar org-src-fontify-natively t)
-          (defvar org-confirm-babel-evaluate nil))
-  :config (org-babel-do-load-languages
-           'org-babel-load-languages
-           '((C . t) (haskell . t) (emacs-lisp . t) (latex . t) (python . t))))
-
-
-(use-package company
-  :demand
-  :init (defvar company-idle-delay 0)
-  :config (global-company-mode)
-  :diminish company-mode)
-
+;; C/C++
 (use-package irony
-  :commands irony-mode
-  :init (progn
-          (add-hook 'c++-mode-hook 'irony-mode)
-          (add-hook 'c-mode-hook 'irony-mode)
-          (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)))
+  :defer
+  :init
+  (progn
+    (add-hook 'c++-mode-hook 'irony-mode)
+    (add-hook 'c-mode-hook 'irony-mode)
+    (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)))
 
 (use-package company-irony
-  :after irony)
+  :after irony
+  :config (add-to-list 'company-backends '(company-irony)))
 (use-package company-irony-c-headers
   :after irony
-  :config (add-to-list 'company-backends '(company-irony-c-headers company-irony)))
-
-(use-package flycheck
-  :demand                               ;Pretty much in every mode, might as well
-  :config (global-flycheck-mode))
+  :config (add-to-list 'company-backends '(company-irony-c-headers)))
 
 (use-package flycheck-irony
   :after irony

(global-set-key (kbd "<f4>") 'zsh-terminal)


;;; 
;;; Start of package-based settings
;;; 

;;; Package manager
(require 'package)

  :after irony
  :init (defvar cmake-ide-build-dir "build"))

;; TeX
(use-package tex
  :defer
  :ensure auctex
  :config (setq TeX-parse-self t))

;; Haskell
(use-package haskell-mode
  :init (add-hook 'haskell-mode-hook
                  (lambda () (interactive)
                    (setq evil-auto-indent nil)
                    (interactive-haskell-mode)))
  :config (setq haskell-stylish-on-save t))

;; JS
(use-package js2-mode
  :defer
  :init
  (progn
    (add-to-list 'auto-mode-alist '("\\.jsx$" . js2-jsx-mode))
    (add-to-list 'auto-mode-alist '("\\.js$" . js2-jsx-mode)))
  :config (setq js2-strict-missing-semi-warning nil
                js2-basic-offset 2))
(use-package json-mode
  :defer
  :init (add-to-list 'auto-mode-alist '("\\.json$" . json-mode)))



;;; Generic bindings area

;; Inherit most emacs bindings instead of the few vim
;; insert-mode ones
(setq evil-insert-state-map (make-sparse-keymap))

;; For some reason "<escape>" and "ESC" differ here, it
;; undoes all meta keys otherwise
(amap "<escape>" 'evil-normal-state)

(defhydra hydra-buffer ()
  "Change buffer quickly"
  ("d" evil-next-buffer)
  ("a" evil-prev-buffer)
  ("q" evil-delete-buffer))
(nmap "SPC w" 'hydra-buffer/body)

(nmap "SPC SPC" 'counsel-M-x)
(nmap "SPC 1" 'delete-other-windows
      "SPC 2" 'ivy-switch-buffer
      "SPC 3" 'counsel-find-file
      "SPC 4" 'zsh-terminal)

(defhydra hydra-fonts ()
  "Change font settings interactively"
  ("w" text-scale-increase "larger")
  ("s" text-scale-decrease "smaller")
  ("d" (choose-font-if-exists "Dina") "Dina")
  ("a" (choose-font-if-exists "Source Code Pro") "SCP"))
(nmap "SPC z" 'hydra-fonts/body)

(amap
 "C-<right>" 'sp-forward-sexp
 "C-<left>" 'sp-backward-sexp
 "C-<up>" 'sp-up-sexp
 "C-<down>" 'sp-down-sexp
 "C-S-<right>" 'sp-forward-slurp-sexp
 "C-S-<left>" 'sp-forward-barf-sexp
 "C-S-<up>" 'sp-backward-slurp-sexp
 "C-S-<down>" 'sp-backward-barf-sexp
 "C-M-t" 'sp-transpose-sexp
 "C-M-w" 'sp-unwrap-sexp)


(nmap "SPC g" 'magit-status)
(nmap "C-s" 'swiper)



(provide 'init)
;;; .emacs ends here
