* My emacs config
** Basic configs
#+BEGIN_SRC emacs-lisp
(setq x-alt-keysym 'meta)
(set-keyboard-coding-system 'utf-8)

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(blink-cursor-mode 0)

(set-frame-font "mononoki Nerd Font:pixelsize=15" nil t)
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(add-hook 'text-mode-hook 'display-line-numbers-mode)

(setq scroll-step 1)
;; (setq scroll-margin 1)
(setq echo-keystrokes 0.1)
(setq initial-scratch-message nil)
(defalias 'yes-or-no-p 'y-or-n-p)

(setq backup-directory-alist '(("." . "~/.emacs.d/backup"))
		backup-by-copying t
		version-control t
		delete-old-versions t
		kept-new-versions 20
		kept-old-versions 5)

(server-start)
#+END_SRC

** MELPA and non-MELPA
#+BEGIN_SRC emacs-lisp
(require 'package)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/1"))

(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e")
(autoload 'mu4e "mu4e" "Launch mu4e and show the main window" t)
(add-to-list 'load-path "/home/jozan/.emacs.d/sunrise-commander/")
(autoload 'sunrise "sunrise.el" "qweqwe" t)
(add-to-list 'load-path "/home/jozan/.emacs.d/font-lock+")
(add-to-list 'load-path "/home/jozan/.emacs.d/all-the-icons/")
(add-to-list 'load-path "/home/jozan/.emacs.d/all-the-icons-dired/")
(add-to-list 'load-path "/home/jozan/.emacs.d/icons-in-terminal.el/")
(add-to-list 'load-path "/home/jozan/.emacs.d/gas-mode/")
(autoload 'gas-mode "gas-mode" "AT&T syntax for assembly code" t)
(add-to-list 'load-path "/home/jozan/.emacs.d/monk-8/")
(autoload 'monk "monk" "Cool CD player" t)

(setq package-enable-at-startup nil)
(setq package-check-signature nil)
(package-initialize)
#+END_SRC

** Some org
#+BEGIN_SRC emacs-lisp
;; set key for agenda
(require 'org)
(global-set-key (kbd "C-c a") 'org-agenda)

;;file to save todo items
(setq org-agenda-files (quote ("~/.emacs.d/org/todo/todo.org")))
(setq org-log-done 'time)

;;set priority range from A to C with default A
(setq org-highest-priority ?A)
(setq org-lowest-priority ?C)
(setq org-default-priority ?A)

;;set colours for priorities
(setq org-priority-faces '((?A . (:foreground "#F0DFAF" :weight bold))
						   (?B . (:foreground "LightSteelBlue"))
						   (?C . (:foreground "OliveDrab"))))

;;open agenda in current window
(setq org-agenda-window-setup (quote current-window))

;;capture todo items using C-c C-t t
(define-key global-map (kbd "C-c C-t") 'org-capture)
(setq org-capture-templates
	  '(("t" "todo" entry (file+headline "/home/jozan/.emacs.d/org/todo/todo.org" "Tasks")
		 "* TODO [#A] %?\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n")))

;;open agenda in current window
(setq org-agenda-window-setup (quote current-window))
;;warn me of any deadlines in next 7 days
(setq org-deadline-warning-days 7)
;;show me tasks scheduled or due in next fortnight
(setq org-agenda-span (quote fortnight))
;;don't show tasks as scheduled if they are already shown as a deadline
(setq org-agenda-skip-scheduled-if-deadline-is-shown t)
;;don't give awarning colour to tasks with impending deadlines
;;if they are scheduled to be done
(setq org-agenda-skip-deadline-prewarning-if-scheduled (quote pre-scheduled))
;;don't show tasks that are scheduled or have deadlines in the
;;normal todo list
(setq org-agenda-todo-ignore-deadlines (quote all))
(setq org-agenda-todo-ignore-scheduled (quote all))
;;sort tasks in order of when they are due and then by priority
(setq org-agenda-sorting-strategy
  (quote
   ((agenda deadline-up priority-down)
	(todo priority-down category-keep)
	(tags priority-down category-keep)
	(search category-keep))))

(org-babel-do-load-languages
	'org-babel-load-languages '((C . t )))
(org-babel-do-load-languages
	'org-babel-load-languages '((lisp . t)))
#+END_SRC

** Core packages
*** Evil mode
#+BEGIN_SRC emacs-lisp
(setq evil-want-integration t) ;; This is optional since it's already set to t by default.
(setq evil-want-keybinding nil)
(setq evil-want-C-u-scroll t)
(require 'evil)
(require 'evil-magit)
(require 'evil-mu4e)
;; (require 'evil-collection)
(evil-mode t)
;; (evil-collection-init)


(setq evil-emacs-state-cursor '("#b16286" box))
(setq evil-normal-state-cursor '("#d79921" box))
(setq evil-visual-state-cursor '("#b06597" box))
(setq evil-insert-state-cursor '("#d79921" bar))
(setq evil-replace-state-cursor '("#cc241d" hbar))
(setq evil-operator-state-cursor '("#d79921" hbar))


(evil-define-key 'insert global-map (kbd "C-o") 'delete-other-windows)
(evil-define-key 'insert global-map (kbd "C-k") 'windmove-up)
(evil-define-key 'insert global-map (kbd "C-j") 'windmove-down)
(evil-define-key 'insert global-map (kbd "C-h") 'windmove-left)
(evil-define-key 'insert global-map (kbd "C-l") 'windmove-right)
(evil-define-key 'normal global-map (kbd "C-o") 'delete-other-windows)
(evil-define-key 'normal global-map (kbd "C-k") 'windmove-up)
(evil-define-key 'normal global-map (kbd "C-j") 'windmove-down)
(evil-define-key 'normal global-map (kbd "C-h") 'windmove-left)
(evil-define-key 'normal global-map (kbd "C-l") 'windmove-right)

(global-evil-leader-mode)
(evil-leader/set-leader ",")
(setq evil-leader/in-all-states 1)

(require 'evil-search-highlight-persist)
(global-evil-search-highlight-persist 1)

(evil-leader/set-key "SPC" 'evil-search-highlight-persist-remove-all)
#+END_SRC

*** Evil nerd commenter
#+BEGIN_SRC emacs-lisp
(require 'evil-nerd-commenter)
(evilnc-default-hotkeys)
#+END_SRC

*** Vimish Fold
	#+BEGIN_SRC emacs-lisp
	(require 'vimish-fold)
	(require 'evil-vimish-fold)
	(add-hook 'prog-mode-hook 'evil-vimish-fold-mode)
	(add-hook 'text-mode-hook 'evil-vimish-fold-mode)
	#+END_SRC

*** Centaur tabs
#+BEGIN_SRC emacs-lisp
(require 'centaur-tabs)
(centaur-tabs-mode t)
(centaur-tabs-group-by-projectile-project)

(evil-define-key 'insert global-map (kbd "M-k") 'centaur-tabs-backward)
(evil-define-key 'insert global-map (kbd "M-j") 'centaur-tabs-forward)
(evil-define-key 'normal global-map (kbd "M-k") 'centaur-tabs-backward)
(evil-define-key 'normal global-map (kbd "M-j") 'centaur-tabs-forward)
(global-set-key (kbd "M-k") 'centaur-tabs-backward)
(global-set-key (kbd "M-j") 'centaur-tabs-forward)

(setq centaur-tabs-set-icons			t
	  centaur-tabs-gray-out-icons		'buffer
	  centaur-tabs-set-close-button		nil
	  centaur-tabs-set-modified-marker	t
	  centaur-tabs-modified-marker		"[+]"
	  centaur-tabs-height				1
	  centaur-tabs-style				"bar"
	  centaur-tabs-set-bar				'left
	  centaur-tabs-change-fonts			"mononoki Nerd Font")

(defun centaur-tabs-hide-tab (x)
	(let ((name (format "%s" x)))
		(or
			(string-prefix-p "*epc" name)
			(string-prefix-p "*helm" name)
			(string-prefix-p "*Helm" name)
			(string-prefix-p "*Compile-Log*" name)
			(string-prefix-p "*compilation*" name)
			(string-prefix-p "*lsp" name)
			(string-prefix-p "*elfeed-log*" name)
			(string-prefix-p "*elfeed-search*" name)
			(string-prefix-p "*elfeed-entry*" name)
			(string-prefix-p "*scratch*" name)
			(string-prefix-p "*Messages*" name)
			(string-prefix-p "todo.org" name)
			(string-prefix-p "*Mingus Help*" name)
			(string-prefix-p "*Mingus*" name)
			(string-prefix-p "*Mingus Browser*" name)
			(and (string-prefix-p "magit" name)
				(not (file-name-extension name))))))

(add-hook 'dashboard-mode-hook #'centaur-tabs-local-mode)
(add-hook 'neotree-mode-hook #'centaur-tabs-local-mode)
(add-hook 'calendar-mode-hook #'centaur-tabs-local-mode)
(add-hook 'org-agenda-mode-hook #'centaur-tabs-local-mode)
(add-hook 'helpful-mode-hook #'centaur-tabs-local-mode)
(add-hook 'term-mode-hook #'centaur-tabs-local-mode)
#+END_SRC

*** Dashboard
#+BEGIN_SRC emacs-lisp
(require 'dashboard)
(dashboard-setup-startup-hook)

(setq dashboard-banner-logo-title	"Welcome back to Emacs, partner!"
	  dashboard-startup-banner		'official
	  dashboard-set-init-info		nil
	  dashboard-set-footer			nil
	  dashboard-center-content		t
	  dashboard-show-shortcuts		nil
	  dashboard-set-heading-icons	t
	  dashboard-set-file-icons		nil
	  dashboard-set-navigator		t
	  show-week-agenda-p			t)
	  
(setq dashboard-items '((projects . 10)
						(recents . 5)
						(agenda . 5)))

(add-to-list 'evil-emacs-state-modes 'dashboard-mode)
#+END_SRC

*** Golden ratio
#+BEGIN_SRC emacs-lisp
;; (require 'golden-ratio)
;; (golden-ratio-mode 1)
;; (setq golden-ratio-adjust-factor		.9
;; 	  golden-ratio-wide-adjust-factor	.9)
#+END_SRC

*** mu4e
#+BEGIN_SRC emacs-lisp
(require 'org-mime)
(require 'mu4e)

(setq mu4e-maildir (expand-file-name "/home/jozan/Maildir"))

(setq mu4e-get-mail-command "/usr/local/bin/mbsync -c /home/jozan/.emacs.d/mu4e/.mbsyncrc -a")
(setq mu4e-update-interval 300)
(setq mu4e-index-update-in-background t)
(setq mu4e-headers-auto-update t)
(setq mu4e-index-update-error-warning t)
(setq mu4e-compose-signature-auto-include nil)
(setq mu4e-compose-format-flowed t)
(setq mu4e-view-prefer-html t)
(add-to-list 'mu4e-view-actions
			 '("ViewInBrowser" . mu4e-action-view-in-browser) t)

;; enable inline images
(setq mu4e-view-show-images t)

;; use imagemagick, if available
(when (fboundp 'imagemagick-register-types)
  (imagemagick-register-types))

;; every new email composition gets its own frame!
(setq mu4e-compose-in-new-frame t)

;; don't save message to Sent Messages, IMAP takes care of this
(setq mu4e-sent-messages-behavior 'delete)

(add-hook 'mu4e-view-mode-hook #'visual-line-mode)

;; <tab> to navigate to links, <RET> to open them in browser
(add-hook 'mu4e-view-mode-hook
		  (lambda()
			;; try to emulate some of the eww key-bindings
			(local-set-key (kbd "<RET>") 'mu4e~view-browse-url-from-binding)
			(local-set-key (kbd "<tab>") 'shr-next-link)
			(local-set-key (kbd "<backtab>") 'shr-previous-link)))

;; from https://www.reddit.com/r/emacs/comments/bfsck6/mu4e_for_dummies/elgoumx
(add-hook 'mu4e-headers-mode-hook
		  (defun my/mu4e-change-headers ()
			(interactive)
			(setq mu4e-headers-fields
				  `((:human-date . 25) ;; alternatively, use :date
					(:flags . 6)
					(:from . 22)
					(:thread-subject . ,(- (window-body-width) 70)) ;; alternatively, use :subject
					(:size . 7)))))

;; spell check
(add-hook 'mu4e-compose-mode-hook
		  (defun my-do-compose-stuff ()
			"My settings for message composition."
			(visual-line-mode)
			(org-mu4e-compose-org-mode)
			(use-hard-newlines -1)
			(flyspell-mode)))

(require 'smtpmail)

;;rename files when moving
;;NEEDED FOR MBSYNC
(setq mu4e-change-filenames-when-moving t)

;;set up queue for offline email
;;use mu mkdir  ~/Maildir/acc/queue to set up first
(setq smtpmail-queue-mail nil)  ;; start in normal mode

;;from the info manual
(setq mu4e-attachment-dir  "/home/jozan/Downloads")

(setq message-kill-buffer-on-exit t)
(setq mu4e-compose-dont-reply-to-self t)
(setq mu4e-completing-read-function 'completing-read)

;; (require 'org-mu4e)

;; convert org mode to HTML automatically
;; (setq org-mu4e-convert-to-html t)

;;from vxlabs config
;; show full addresses in view message (instead of just names)
;; toggle per name with M-RET
(setq mu4e-view-show-addresses 't)

;; don't ask when quitting
(setq mu4e-confirm-quit nil)

;; mu4e-context
(setq mu4e-context-policy 'pick-first)
(setq mu4e-compose-context-policy 'always-ask)
(setq mu4e-contexts
	  (list
	   (make-mu4e-context
		:name "work" ;;for acc1-gmail
		:enter-func (lambda () (mu4e-message "Entering context work"))
		:leave-func (lambda () (mu4e-message "Leaving context work"))
		:match-func (lambda (msg)
					  (when msg
						(mu4e-message-contact-field-matches
						 msg '(:from :to :cc :bcc) "bousset.rudy@gmail.com")))
		:vars '((user-mail-address . "bousset.rudy@gmail.com")
				(user-full-name . "Rudy Bousset")
				(mu4e-sent-folder . "/acc1-gmail/[acc1].Sent Mail")
				(mu4e-drafts-folder . "/acc1-gmail/[acc1].drafts")
				(mu4e-trash-folder . "/acc1-gmail/[acc1].Trash")
				(mu4e-compose-signature . (concat "Formal Signature\n" " "))
				(mu4e-compose-format-flowed . t)
				(smtpmail-queue-dir . "~/Maildir/acc1-gmail/queue/cur")
				;; (message-send-mail-function . smtpmail-send-it)
				(smtpmail-smtp-user . "bousset.rudy")
				;; (smtpmail-starttls-credentials . (("smtp.gmail.com" 587 nil nil)))
				;; (smtpmail-auth-credentials . (expand-file-name "~/.authinfo.gpg"))
				(smtpmail-default-smtp-server . "smtp.gmail.com")
				(smtpmail-smtp-server . "smtp.gmail.com")
				(smtpmail-smtp-service . 587)
				(smtpmail-debug-info . t)
				(smtpmail-debug-verbose . t)
				(mu4e-maildir-shortcuts . ( ("/acc1-gmail/INBOX"            . ?i)
											("/acc1-gmail/[acc1].Sent Mail" . ?s)
											("/acc1-gmail/[acc1].Trash"     . ?t)
											("/acc1-gmail/[acc1].All Mail"  . ?a)
											("/acc1-gmail/[acc1].Starred"   . ?r)
											("/acc1-gmail/[acc1].drafts"    . ?d)
											))))))

(require 'mu4e-alert)
(mu4e-alert-set-default-style 'libnotify)
(add-hook 'after-init-hook #'mu4e-alert-enable-notifications)
(add-hook 'after-init-hook #'mu4e-alert-enable-mode-line-display)
#+END_SRC

*** w3m
#+BEGIN_SRC emacs-lisp
(require 'w3m-load)
(setq w3m-home-page "https://start.duckduckgo.com/")
(setq w3m-default-display-inline-images t)
;; (define-key w3m-mode-map "w" 'right-word)
;; (define-key w3m-mode-map "b" 'left-word)
;; (define-key w3m-mode-map "<" 'scroll-left)
;; (define-key w3m-mode-map ">" 'scroll-right)
;; (define-key w3m-mode-map (kbd "C-d") 'evil-scroll-page-down)
;; (define-key w3m-mode-map (kbd "C-u") 'evil-scroll-page-up)
;; (define-key w3m-mode-map "H" 'w3m-view-previous-page)
;; (define-key w3m-mode-map "L" 'w3m-view-next-page)
;; (define-key w3m-mode-map "o" 'w3m-goto-url)
;; (define-key w3m-mode-map "O" 'w3m-goto-url-new-session)
;; (define-key w3m-mode-map "v" 'w3m-view-image)
;; (define-key w3m-mode-map "$" 'w3m-end-of-line)
;; (define-key w3m-mode-map "^" 'w3m-beginning-of-line)
;; (define-key w3m-mode-map (kbd "M-j") 'w3m-next-buffer)
;; (define-key w3m-mode-map (kbd "M-k") 'w3m-previous-buffer)
;; (define-key w3m-mode-map "t" 'w3m-copy-buffer)
#+END_SRC

*** NeoTree
#+BEGIN_SRC emacs-lisp
(require 'neotree)
(setq neo-vc-integration '(face))
(evil-define-key 'normal neotree-mode-map (kbd "TAB") 'neotree-enter)
(evil-define-key 'normal neotree-mode-map (kbd "SPC") 'neotree-quick-look)
(evil-define-key 'normal neotree-mode-map (kbd "q") 'neotree-hide)
(evil-define-key 'normal neotree-mode-map (kbd "RET") 'neotree-enter)
(evil-define-key 'normal neotree-mode-map (kbd "g") 'neotree-refresh)
(evil-define-key 'normal neotree-mode-map (kbd "n") 'neotree-next-line)
(evil-define-key 'normal neotree-mode-map (kbd "p") 'neotree-previous-line)
(evil-define-key 'normal neotree-mode-map (kbd "A") 'neotree-stretch-toggle)
(evil-define-key 'normal neotree-mode-map (kbd "H") 'neotree-hidden-file-toggle)
(evil-define-key 'normal neotree-mode-map (kbd "|") 'neotree-enter-vertical-split)
(evil-define-key 'normal neotree-mode-map (kbd "S") 'neotree-enter-vertical-split)
(evil-define-key 'normal neotree-mode-map (kbd "/") 'neotree-enter-horizontal-split)
(evil-define-key 'normal neotree-mode-map (kbd "s") 'neotree-enter-horizontal-split)
#+END_SRC

*** Helm, projectile
#+BEGIN_SRC emacs-lisp
(require 'helm-config)
(require 'helm-misc)
(require 'helm-projectile)
(require 'helm-locate)

(global-set-key (kbd "M-x") 'helm-M-x)
(global-set-key (kbd "C-x C-f") #'helm-find-files)
(global-set-key (kbd "M-p") #'helm-projectile-switch-project)
(global-set-key (kbd "C-x C-b") #'helm-buffers-list)
(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-z") 'helm-select-action)

(setq helm-quick-update					t
	  helm-bookmark-show-location		t
	  helm-buffers-fuzzy-matching		t
	  helm-make-executable				"/usr/local/bin/gmake"
	  helm-make-nproc					5
	  helm-split-window-in-side-p		t)

(defun helm-my-buffers ()
  (interactive)
  (let ((helm-ff-transformer-show-only-basename nil))
	(helm-other-buffer '(helm-c-source-buffers-list
			 helm-c-source-elscreen
			 helm-c-source-projectile-files-list
			 helm-c-source-ctags
			 helm-c-source-recentf
			 helm-c-source-locate)
			   "*helm-my-buffers*")))

(helm-mode 1)
(projectile-mode +1)
#+END_SRC

*** DOOM Modeline
#+BEGIN_SRC emacs-lisp
(setq display-time-string-forms
	   '((propertize (concat " " 24-hours ":" minutes " "))))

(require 'doom-modeline)
(doom-modeline-mode 1)
(setq doom-modeline-height 30)
(setq doom-modeline-project-detection 'projectile)
(setq doom-modeline-buffer-file-name-style 'truncate-upto-project)
(setq doom-modeline-icon (display-graphic-p))
(setq doom-modeline-major-mode-icon t)
(setq doom-modeline-major-mode-color-icon t)
(setq doom-modeline-buffer-state-icon t)
(setq doom-modeline-buffer-modification-icon t)
(setq doom-modeline-unicode-fallback t)
(setq doom-modeline-enable-word-count nil)
(setq doom-modeline-buffer-encoding nil)
(setq doom-modeline-indent-info nil)
(setq doom-modeline-checker-simple-format t)
(setq doom-modeline-number-limit 99)
(setq doom-modeline-vcs-max-length 12)
(setq doom-modeline-persp-name t)
(setq doom-modeline-lsp t)
(setq doom-modeline-github nil)
(setq doom-modeline-github-interval (* 30 60))
(setq doom-modeline-modal-icon t)
(setq doom-modeline-mu4e t)
(setq doom-modeline-gnus nil)
(setq doom-modeline-irc t)
(setq doom-modeline-irc-stylize 'identity)
(setq doom-modeline-env-version t)
(setq doom-modeline-env-python-executable "python-shell-interpreter")
(setq doom-modeline-env-ruby-executable "ruby")
(setq doom-modeline-env-perl-executable "perl")
(setq doom-modeline-env-go-executable "go")
(setq doom-modeline-env-elixir-executable "iex")
(setq doom-modeline-env-rust-executable "rustc")
(setq doom-modeline-env-load-string "...")
(setq doom-modeline-before-update-env-hook nil)
(setq doom-modeline-after-update-env-hook nil)
(display-battery-mode)
(column-number-mode)
(display-time)
(doom-themes-neotree-config)
#+END_SRC

*** Colors and rainbows
#+BEGIN_SRC emacs-lisp
(require 'color-identifiers-mode)
(global-color-identifiers-mode)

(require 'rainbow-delimiters)
(add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
#+END_SRC

*** C default style
#+BEGIN_SRC emacs-lisp
(setq c-default-style "bsd")
#+END_SRC

*** Autopair
#+BEGIN_SRC emacs-lisp
(require 'autopair)
(autopair-global-mode)
#+END_SRC

*** Paredit
#+BEGIN_SRC emacs-lisp
(require 'paredit)
(defadvice paredit-mode (around disable-autopairs-around (arg))
  ad-do-it
  (if (null ad-return-value)
	(autopair-mode 1)
  (autopair-mode -1)
))
(ad-activate 'paredit-mode)
#+END_SRC

*** Magit
#+BEGIN_SRC emacs-lisp
(require 'magit)

(defun my/magit-kill-buffers ()
	"Restore window configuration and kill all Magit buffers.
Attribution: URL `https://manuel-uberti.github.io/emacs/2018/02/17/magit-bury-buffer/'"
	(interactive)
	(let ((buffers (magit-mode-get-buffers)))
		(magit-restore-window-configuration)
	    (mapc #'kill-buffer buffers)))

(bind-key "q" #'my/magit-kill-buffers magit-status-mode-map)
(evil-define-key 'insert magit-status-mode-map (kbd "q") #'my/magit-kill-buffers)
(evil-define-key 'normal magit-status-mode-map (kbd "q") #'my/magit-kill-buffers)
#+END_SRC

*** Ranger
#+BEGIN_SRC emacs-lisp
(require 'ranger)
(ranger-override-dired-mode t)
(add-hook 'dired-mode-hook 'auto-revert-mode)
#+END_SRC

*** Lock windows
#+BEGIN_SRC emacs-lisp
(defun my/toggle-window-dedicated ()
  "Control whether or not Emacs is allowed to display another
buffer in current window."
  (interactive)
  (message
   (if (let (window (get-buffer-window (current-buffer)))
		 (set-window-dedicated-p window (not (window-dedicated-p window))))
	   "%s: locked"
	 "%s is up for grabs")
   (current-buffer)))

(global-set-key (kbd "C-c t") 'my/toggle-window-dedicated)
#+END_SRC

*** cargo
#+BEGIN_SRC emacs-lisp
(require 'cargo)
(add-hook 'rust-mode-hook 'cargo-minor-mode)
#+END_SRC

*** yasnippet
#+BEGIN_SRC emacs-lisp
(require 'yasnippet)
(require 'yasnippet-snippets)
(require 'yasnippet-classic-snippets)
(require 'helm-c-yasnippet)
(yas-reload-all)
(add-hook 'prog-mode-hook #'yas-minor-mode)
#+END_SRC

*** Tabs and stuff
#+BEGIN_SRC emacs-lisp
(defun minibuffer-keyboard-quit ()
  "Abort recursive edit.
In Delete Selection mode, if the mark is active, just deactivate it;
then it takes a second \\[keyboard-quit] to abort the minibuffer."
  (interactive)
  (if (and delete-selection-mode transient-mark-mode mark-active)
	  (setq deactivate-mark  t)
	(when (get-buffer "*Completions*") (delete-windows-on "*Completions*"))
	(abort-recursive-edit)))
(define-key evil-normal-state-map [escape] 'keyboard-quit)
(define-key evil-visual-state-map [escape] 'keyboard-quit)
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
(global-set-key [escape] 'evil-exit-emacs-state)

(defun my/insert-tab-char ()
  (interactive)
  (insert "\t"))

(define-key evil-insert-state-map [tab] 'my/insert-tab-char)
(setq my/tab-stop 4)
(setq-default indent-tabs-mode t)
(setq tab-always-indent 'complete)
(setq-default tab-width my/tab-stop)
(setq tab-width my/tab-stop)
(setq-default c-basic-offset my/tab-stop)
(setq-default cperl-indent-level my/tab-stop)
#+END_SRC

*** all the icons
#+BEGIN_SRC emacs-lisp
(require 'font-lock)
(require 'font-lock+)
(require 'all-the-icons)
(load "all-the-icons-dired.el")
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)
#+END_SRC

*** minugs
#+BEGIN_SRC emacs-lisp
(require 'mingus)
(add-to-list 'evil-emacs-state-modes 'mingus-help-mode)
(add-to-list 'evil-emacs-state-modes 'mingus-playlist-mode)
(add-to-list 'evil-emacs-state-modes 'mingus-browse-mode)
#+END_SRC

*** elfeed
#+BEGIN_SRC emacs-lisp
(require 'url)
(require 'elfeed)
(require 'elfeed-org)
(elfeed-org)
(setq rmh-elfeed-org-files (list "~/.emacs.d/org/elfeed/elfeed.org"))

(defun my/elfeed-show-all ()
	(interactive)
	(bookmark-maybe-load-default-file)
	(bookmark-jump "elfeed-all"))

(defun my/elfeed-show-news ()
	(interactive)
	(bookmark-maybe-load-default-file)
	(bookmark-jump "elfeed-news"))

(defun my/elfeed-show-youtube ()
	(interactive)
	(bookmark-maybe-load-default-file)
	(bookmark-jump "elfeed-youtube"))

(defun my/elfeed-load-db-and-open ()
	(interactive)
	(elfeed-db-load)
	(elfeed)
	(elfeed-search-update--force))

(defun my/elfeed-save-db-and-bury ()
	(interactive)
	(elfeed-db-save)
	(kill-buffer "*elfeed-log*")
	(kill-buffer "*elfeed-search*")
	(kill-buffer "elfeed.org"))

(defun my/elfeed-v-mpv (url)
	"Watch a video from URL in MPV"
	(setq quality (completing-read "Max height resolution (0 for unlimited): " '("0" "360" "480" "720" "1080")))
	(setq fmt (if (= 0 (string-to-number quality)) "" (format "--ytdl-format=bestvideo[height<=?%s]+bestaudio/best" quality)))
	(async-shell-command (format "mpv \"%s\" \"%s\"" fmt url)))


(defun my/elfeed-view-mpv (&optional use-generic-p)
	"Youtube-feed link"
	(interactive "P")
	(let ((entries (elfeed-search-selected)))
		(cl-loop for entry in entries
			do (elfeed-untag entry 'unread)
			when (elfeed-entry-link entry)
			do (my/elfeed-v-mpv it))
			(mapc #'elfeed-search-update-entry entries)
			(unless (use-region-p) (forward-line))))
			
(defun my/elfeed-d-download (url)
	"Download media links"
	(async-shell-command (format "cd ~/Downloads && curl -O \"%s\"" url)))

(defun my/elfeed-download-link (&optional use-generic-p)
	"Download media links"
	(interactive "P")
	(let ((entries (elfeed-search-selected)))
		(cl-loop for entry in entries
			do (elfeed-untag entry 'unread)
			when (elfeed-entry-link entry)
			do (my/elfeed-d-download it))
			(mapc #'elfeed-search-update-entry entries)
			(unless (use-region-p) (forward-line))))

(define-key elfeed-search-mode-map (kbd "q") 'my/elfeed-save-db-and-bury)
(define-key elfeed-search-mode-map (kbd "A") 'my/elfeed-show-all)
(define-key elfeed-search-mode-map (kbd "N") 'my/elfeed-show-news)
(define-key elfeed-search-mode-map (kbd "Y") 'my/elfeed-show-youtube)
(define-key elfeed-search-mode-map (kbd "v") 'my/elfeed-view-mpv)
(define-key elfeed-search-mode-map (kbd "d") 'my/elfeed-download-link)
(define-key elfeed-search-mode-map (kbd "h") 'backward-char)
(define-key elfeed-search-mode-map (kbd "j") 'forward-line)
(define-key elfeed-search-mode-map (kbd "k") 'previous-line)
(define-key elfeed-search-mode-map (kbd "l") 'forward-char)

(add-to-list 'evil-emacs-state-modes 'elfeed-search-mode)
(add-to-list 'evil-emacs-state-modes 'elfeed-show-mode)
#+END_SRC

*** which-key
#+BEGIN_SRC emacs-lisp
(require 'which-key)
(which-key-mode)
#+END_SRC

*** shell-pop
#+BEGIN_SRC emacs-lisp
(require 'shell-pop)
(setq my/shell-pop-shell-type
	(quote
	("ansi-term" "*ansi-term*"
	(lambda nil
	(ansi-term shell-pop-term-shell)))))

(setq shell-pop-term-shell "/usr/local/bin/zsh")
(add-to-list 'evil-emacs-state-modes 'term-mode)
#+END_SRC

*** org-bullets
#+BEGIN_SRC emacs-lisp
(require 'org-bullets)
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
#+END_SRC

*** toc-org
#+BEGIN_SRC emacs-lisp
(require 'toc-org)
(add-hook 'org-mode-hook 'toc-org-mode)
;; enable in markdown, too
(add-hook 'markdown-mode-hook 'toc-org-mode)
(define-key markdown-mode-map (kbd "\C-c\C-o") 'toc-org-markdown-follow-thing-at-point)
#+END_SRC

*** irony
	#+BEGIN_SRC emacs-lisp
	(require 'irony)
	(add-hook 'c++-mode-hook 'irony-mode)
	(add-hook 'c-mode-hook 'irony-mode)
	(add-hook 'objc-mode-hook 'irony-mode)
	(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
	#+END_SRC

*** company
	#+BEGIN_SRC emacs-lisp
	(require 'company)
	(require 'company-irony)
	;; (add-to-list 'company-backends 'company-irony)
	;; (add-to-list 'company-backends 'company-yasnippet)
	(add-hook 'after-init-hook 'global-company-mode)
	(global-company-mode)
	;; company delay until suggestions are shown
	(setq company-idle-delay 0)
	
	;; weight by frequency
	(setq company-transformers '(company-sort-by-occurrence))
	
	;; Add yasnippet support for all company backends
	;; https://github.com/syl20bnr/spacemacs/pull/179
	(defvar company-mode/enable-yas t "Enable yasnippet for all backends.")
	
	(defun company-mode/backend-with-yas (backend)
	  (if (or (not company-mode/enable-yas) (and (listp backend)    (member 'company-yasnippet backend)))
	  backend
	(append (if (consp backend) backend (list backend))
	        '(:with company-yasnippet))))
	
	(setq company-backends (mapcar #'company-mode/backend-with-yas company-backends))
	#+END_SRC

** Compilation
*** Close window after errorless compilation
#+BEGIN_SRC emacs-lisp
(setq compilation-finish-function
(lambda (buf str)
	(if (null (string-match ".*exited abnormally.*" str))
		;;no errors, make the compilation window go away in a few seconds
		(progn
		  (run-at-time
		   "0.5 sec" nil 'delete-windows-on "*compilation*")
		  (message "")))))
#+END_SRC

*** Compilation functions
#+BEGIN_SRC emacs-lisp
(defun my/exec-f5 ()
  (interactive)
  (defvar make)
  (setq make "gmake -j5 asan")
  (save-buffer)
  (compile make)
  (compilation-finish-function)) 

(defun my/exec-f6 ()
  (interactive)
  (defvar exec)
  (setq exec "./a.out; ret=$?; echo \"\e[1;35m~>\"; if [ $ret -ne 0 ]; then echo -n \"\e[1;31m$ret\"; if [ $ret -eq 127 ]; then echo \" - Missing a.out, comipler error! \"; exit; elif [ $ret -eq 134 ]; then echo \" - Abort! \"; elif [ $ret -eq 138 ]; then echo \" - Bus error! \"; elif [ $ret -eq 139 ]; then echo \" - Segmentation fault! \"; fi; fi; echo \"\e[1;35m\n\n.emacs v1.5 Tilde Edition by Joe\"")
  (async-shell-command exec))
#+END_SRC

** Custom functions
*** startsoon-mode
	#+BEGIN_SRC emacs-lisp
	(defun my/startsoon ()
		(interactive)
		(split-window-right)
		(windmove-right)
		(split-window-below)
		(enlarge-window 10)
		(windmove-down)
		(switch-to-buffer "*Mingus*")
		(mingus-refresh)
		(windmove-up)
		(term "/usr/home/jozan/.local/bin/startsoon")
		(windmove-left)
		(zone))
	#+END_SRC

*** brb-mode
	#+BEGIN_SRC emacs-lisp
	(defun my/brb ()
		(interactive)
		(split-window-right)
		(windmove-right)
		(split-window-below)
		(enlarge-window 10)
		(windmove-down)
		(switch-to-buffer "*Mingus*")
		(mingus-refresh)
		(windmove-up)
		(term "/usr/home/jozan/.local/bin/brb")
		(windmove-left)
		(zone))
	#+END_SRC

** Other key bindings
#+BEGIN_SRC emacs-lisp
(global-set-key [f1] 'shell-pop)
(global-set-key [f2] 'neotree-toggle)
(global-set-key [f4] 'helm-make-projectile)
(global-set-key [f5] 'my/exec-f5)
(global-set-key [f6] 'my/exec-f6)
(global-set-key (kbd "C-x d") 'dired)
(global-set-key (kbd "M-1") 'shell-command)
(global-set-key (kbd "M-7") 'async-shell-command)

(shell-pop--set-shell-type 'my/shell-pop-shell-type my/shell-pop-shell-type)
#+END_SRC