init.el 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. ;; TODO:
  2. ;; Easier undo tree traversal
  3. ;; Replace evil-leader with general
  4. ;;;; Startup
  5. (setq inhibit-splash-screen t
  6. inhibit-startup-echo-area-message t
  7. initial-scratch-message "" ; I like things empty.
  8. initial-major-mode 'text-mode) ; I'm usually not writing elisp.
  9. ;; Base
  10. (setq ring-bell-function 'ignore) ; Disable beep & flash
  11. (blink-cursor-mode 0)
  12. ;; No scroll bar
  13. (when (boundp 'scroll-bar-mode)
  14. (scroll-bar-mode -1))
  15. ;; Disable toolbar
  16. (when (display-graphic-p)
  17. (tool-bar-mode -1))
  18. ;; smoother scrolling
  19. (setq scroll-margin 0
  20. scroll-conservatively 9999
  21. scroll-step 1)
  22. ;; Line settings and indicators
  23. (setq visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow))
  24. (setq-default left-fringe-width nil)
  25. (setq-default indicate-empty-lines t)
  26. ;; All yes or no prompts are y or n
  27. (defalias 'yes-or-no-p 'y-or-n-p)
  28. ;; Never follow symlinks
  29. (setq vc-follow-symlinks nil)
  30. ;;; Leave the OS clipboard alone (use evil's "+ and "* instead)
  31. ; Don't copy and paste to the clipboard
  32. (setq select-enable-clipboard nil)
  33. (setq x-select-enable-clipboard nil)
  34. ; Don't save to the clipboard on exit
  35. (setq x-select-enable-clipboard-manager nil)
  36. ;; Text and Notes
  37. (setq sentence-end-double-space nil)
  38. ;; Save minibar history
  39. (savehist-mode 1)
  40. (setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring))
  41. ;; Always show matching parens
  42. (show-paren-mode t)
  43. ;; Backups (from https://stackoverflow.com/questions/151945/how-do-i-control-how-emacs-makes-backup-files/20824625#20824625)
  44. (setq version-control t ;; Use version numbers for backups.
  45. kept-new-versions 10 ;; Number of newest versions to keep.
  46. kept-old-versions 0 ;; Number of oldest versions to keep.
  47. delete-old-versions t ;; Don't ask to delete excess backup versions.
  48. backup-by-copying t) ;; Copy all files, don't rename them.
  49. (setq vc-make-backup-files t) ;; Backup versioned files
  50. ;; Default and per-save backups go here:
  51. (setq backup-directory-alist '(("" . "~/.emacs.d/backups/per-save")))
  52. (defun force-backup-of-buffer ()
  53. ;; Make a special "per session" backup at the first save of each
  54. ;; emacs session.
  55. (when (not buffer-backed-up)
  56. ;; Override the default parameters for per-session backups.
  57. (let ((backup-directory-alist '(("" . "~/.emacs.d/backups/per-session")))
  58. (kept-new-versions 3))
  59. (backup-buffer)))
  60. ;; Make a "per save" backup on each save. The first save results in
  61. ;; both a per-session and a per-save backup, to keep the numbering
  62. ;; of per-save backups consistent.
  63. (let ((buffer-backed-up nil))
  64. (backup-buffer)))
  65. (add-hook 'before-save-hook 'force-backup-of-buffer)
  66. ;; Autosave files
  67. (setq auto-save-file-name-transforms
  68. `((".*" , "~/.emacs.d/backups/auto-saves" t)))
  69. ;; remember cursor position
  70. (toggle-save-place-globally)
  71. ;;; Spelling
  72. ;; map ]s and [s to next and previously wrong word
  73. ;; move point to previous error
  74. ;; based on code by hatschipuh at
  75. ;; http://emacs.stackexchange.com/a/14912/2017
  76. (defun flyspell-goto-previous-error (arg)
  77. "Go to arg previous spelling error."
  78. (interactive "p")
  79. (while (not (= 0 arg))
  80. (let ((pos (point))
  81. (min (point-min)))
  82. (if (and (eq (current-buffer) flyspell-old-buffer-error)
  83. (eq pos flyspell-old-pos-error))
  84. (progn
  85. (if (= flyspell-old-pos-error min)
  86. ;; goto beginning of buffer
  87. (progn
  88. (message "Restarting from end of buffer")
  89. (goto-char (point-max)))
  90. (backward-word 1))
  91. (setq pos (point))))
  92. ;; seek the next error
  93. (while (and (> pos min)
  94. (let ((ovs (overlays-at pos))
  95. (r '()))
  96. (while (and (not r) (consp ovs))
  97. (if (flyspell-overlay-p (car ovs))
  98. (setq r t)
  99. (setq ovs (cdr ovs))))
  100. (not r)))
  101. (backward-word 1)
  102. (setq pos (point)))
  103. ;; save the current location for next invocation
  104. (setq arg (1- arg))
  105. (setq flyspell-old-pos-error pos)
  106. (setq flyspell-old-buffer-error (current-buffer))
  107. (goto-char pos)
  108. (if (= pos min)
  109. (progn
  110. (message "No more miss-spelled word!")
  111. (setq arg 0))
  112. ))))
  113. ;;;; Packages
  114. ;;; use-package example:
  115. ; (use-package foo
  116. ; :init ; Runs before loading the package. WIll always run, even if foo isn't on this system.
  117. ; :config ; Runs after.
  118. ; :bind (("M-s O" . action)
  119. ; ("" . some-other-action))
  120. ; :commands foo-mode ; Creates autoloads for commands: defers loading until called.
  121. ; )
  122. ;; Package installation
  123. (require 'package)
  124. (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))
  125. (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
  126. (setq package-enable-at-startup nil)
  127. (package-initialize)
  128. (unless (package-installed-p 'use-package)
  129. (package-refresh-contents)
  130. (package-install 'use-package))
  131. (eval-when-compile
  132. (require 'use-package))
  133. ;; Keep track of whether or not we need to refresh package contents
  134. (setq packages-installed-this-session 0)
  135. ;; Function to ensure every package in installed, and ask if it isn't.
  136. (defun ensure-package-installed (&rest packages)
  137. (mapcar
  138. (lambda (package)
  139. (if (package-installed-p package)
  140. nil
  141. (if (y-or-n-p (format "Package %s is missing. Install it? " package))
  142. ;; If this is the 1st install this session, update before install
  143. (cond ((eq packages-installed-this-session 0)
  144. (package-refresh-contents)
  145. (setq packages-installed-this-session 1)
  146. (package-install package))
  147. (t (package-install package))
  148. nil)
  149. package)))
  150. packages))
  151. ;; List of packages to install on all systems
  152. (setq required-packages
  153. '(
  154. iedit
  155. magit
  156. evil-magit
  157. magithub
  158. ;undo-tree
  159. evil
  160. evil-leader
  161. powerline-evil
  162. monokai-theme
  163. challenger-deep-theme
  164. linum-relative
  165. multi-term
  166. neotree
  167. evil-numbers
  168. editorconfig
  169. company
  170. ivy
  171. flx
  172. flycheck
  173. flycheck-pos-tip
  174. evil-surround
  175. diminish
  176. dtrt-indent
  177. undohist))
  178. ;; List of optional packages
  179. (setq optional-packages
  180. '(
  181. flymd
  182. markdown-mode
  183. latex-preview-pane
  184. tide
  185. web-mode
  186. racket-mode
  187. fuzzy
  188. general))
  189. ;; Check that all packages are installed
  190. (apply 'ensure-package-installed required-packages)
  191. ;; Declare function for optional packages
  192. (defun optional-packages-install ()
  193. (interactive)
  194. (apply 'ensure-package-installed optional-packages))
  195. ;; Activate installed packages
  196. (package-initialize)
  197. (add-to-list 'load-path (expand-file-name "plugins" user-emacs-directory))
  198. (require 'diminish)
  199. (diminish 'visual-line-mode)
  200. (diminish 'abbrev-mode)
  201. (use-package autorevert
  202. :diminish auto-revert-mode)
  203. (use-package recentf
  204. :config
  205. (recentf-mode 1)
  206. (setq recentf-max-saved-items 200
  207. recentf-max-menu-items 15))
  208. (use-package evil
  209. :config
  210. (evil-mode t)
  211. (setq evil-want-C-i-jump nil)
  212. (setq evil-default-state 'normal)
  213. ;; Move all elements of evil-emacs-state-modes to evil-motion-state-modes
  214. (setq evil-motion-state-modes (append evil-emacs-state-modes evil-motion-state-modes))
  215. (setq evil-emacs-state-modes (list 'magit-popup-mode))
  216. (delete 'magit-popup-mode evil-motion-state-modes)
  217. ;; Delete info bindings for evil to take over
  218. (define-key Info-mode-map "g" nil)
  219. (define-key Info-mode-map "n" nil)
  220. (define-key Info-mode-map "p" nil)
  221. ;; Vim removing of windows
  222. (define-key evil-window-map (kbd "q") 'delete-window)
  223. (define-key evil-window-map (kbd "C-q") 'delete-window)
  224. ; Don't echo evil's states
  225. (setq evil-insert-state-message nil)
  226. (setq evil-visual-state-message nil)
  227. ;; eval the last sexp while in normal mode (include the character the cursor is currently on)
  228. (defun evil-eval-last-sexp ()
  229. (interactive)
  230. (evil-append 1)
  231. (eval-last-sexp nil)
  232. (evil-normal-state))
  233. ;; "pull" left and right with zs and ze
  234. (defun hscroll-cursor-left ()
  235. (interactive "@")
  236. (set-window-hscroll (selected-window) (current-column)))
  237. (defun hscroll-cursor-right ()
  238. (interactive "@")
  239. (set-window-hscroll (selected-window) (- (current-column) (window-width) -1)))
  240. ;; Horizontal scrolling
  241. (setq auto-hscroll-mode 't)
  242. (setq hscroll-margin 0
  243. hscroll-step 1)
  244. :bind (:map evil-normal-state-map
  245. ("zs" . hscroll-cursor-left)
  246. ("ze" . hscroll-cursor-right)
  247. ("[s" . flyspell-goto-previous-error)
  248. ("]s" . flyspell-goto-next-error)
  249. ("\C-x \C-e" . evil-eval-last-sexp)
  250. :map Info-mode-map
  251. ("g" . nil)
  252. ("n" . nil)
  253. ("p" . nil)
  254. :map evil-window-map
  255. ("q" . delete-window)
  256. ("C-q" . delete-window)))
  257. (use-package evil-numbers
  258. ;; Increment and decrement (evil-numbers)
  259. :bind (("C-c C-a" . evil-numbers/inc-at-pt)
  260. ("C-c C-d" . evil-numbers/dec-at-pt)))
  261. (use-package undo-tree
  262. :diminish undo-tree-mode)
  263. (use-package undohist
  264. :config
  265. ;; ;; Save undo history under .emacs.d/undohist
  266. (setq undohist-directory "~/.emacs.d/undohist")
  267. (unless (file-exists-p "~/.emacs.d/undohist")
  268. (make-directory "~/.emacs.d/undohist"))
  269. (undohist-initialize))
  270. ;(use-package powerline
  271. ; :config
  272. ; (powerline-evil-vim-color-theme))
  273. (require 'init-powerline)
  274. (use-package web-mode
  275. :config
  276. ;; 2 spaces for an indent
  277. (defun my-web-mode-hook ()
  278. "Hooks for Web mode."
  279. (setq web-mode-markup-indent-offset 2))
  280. (add-hook 'web-mode-hook 'my-web-mode-hook)
  281. ;; Auto-enable web-mode when opening relevent files
  282. (add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
  283. (add-to-list 'auto-mode-alist '("\\.hbs\\'" . web-mode))
  284. (add-to-list 'auto-mode-alist '("\\.handlebars\\'" . web-mode)))
  285. (use-package linum-relative
  286. :diminish linum-relative-mode
  287. :config
  288. (setq linum-relative-current-symbol "")
  289. (linum-mode)
  290. (linum-relative-global-mode))
  291. (use-package flymd
  292. :config
  293. (setq flymd-close-buffer-delete-temp-files t))
  294. ;; Evil leader is Space
  295. (use-package evil-leader
  296. :config
  297. (global-evil-leader-mode)
  298. (evil-leader/set-leader "<SPC>")
  299. (evil-leader/set-key
  300. "d" 'diff-buffer-with-file
  301. ;"b" 'buffer-menu
  302. "b" 'ivy-switch-buffer
  303. "C-b" 'buffer-menu
  304. ;"f" '(lambda () (interactive) (dired '"./"))
  305. "f" 'neotree-toggle
  306. "u" 'undo-tree-visualize
  307. "m" 'recentf-open-files
  308. "l" 'auto-fill-mode
  309. "s" '(lambda ()
  310. (interactive)
  311. ;; use flyspell-mode when in text buffers, otherwise use flyspell-prog-mode
  312. (let* ((current-mode
  313. (buffer-local-value 'major-mode (current-buffer)))
  314. (flyspell-mode-to-call
  315. (if (or (string= current-mode "text-mode") (string= current-mode "markdown-mode"))
  316. 'flyspell-mode
  317. 'flyspell-prog-mode)))
  318. ;; toggle the current flyspell mode, and eval the buffer if we turned it on
  319. (if flyspell-mode
  320. (funcall 'flyspell-mode '0)
  321. (funcall flyspell-mode-to-call)
  322. (flyspell-buffer))))
  323. ;"a" 'auto-complete-mode
  324. "a" 'company-mode
  325. "g" 'magit-status
  326. "M-g" 'magit-dispatch-popup
  327. "c" 'flycheck-mode
  328. ))
  329. (use-package magit
  330. :diminish magit-auto-revert-mode
  331. :config
  332. (setq evil-magit-state 'normal))
  333. (use-package evil-magit
  334. :config
  335. (evil-magit-init))
  336. (use-package magithub
  337. :config
  338. (magithub-feature-autoinject t))
  339. (use-package neotree
  340. :config
  341. ; Set vi-like bindings in neotree-mode that don't conflict with evil
  342. (evil-define-key 'normal neotree-mode-map (kbd "TAB") 'neotree-enter)
  343. (evil-define-key 'normal neotree-mode-map (kbd "SPC") 'neotree-enter)
  344. (evil-define-key 'normal neotree-mode-map (kbd "q") 'neotree-hide)
  345. (evil-define-key 'normal neotree-mode-map (kbd "RET") 'neotree-enter)
  346. (evil-define-key 'normal neotree-mode-map (kbd "h") 'neotree-hidden-file-toggle)
  347. (evil-define-key 'normal neotree-mode-map (kbd "r") 'neotree-refresh)
  348. ;Every time when the neotree window is opened, let it find current file and jump to node.
  349. (setq neo-smart-open t)
  350. ; List of files to hide
  351. (setq neo-hidden-regexp-list '("^\\." "\\.pyc$" "~$" "^#.*#$" "\\.elc$" "\\.class")))
  352. ;; tide/typescript
  353. (setq typescript-indent-level 2)
  354. ;; JavaScript
  355. (setq js-indent-level 2)
  356. (use-package racket-mode
  357. :config
  358. (add-to-list 'auto-mode-alist '("\\.scm\\'" . racket-mode))
  359. ; C-w prefix in racket-REPL
  360. (add-hook 'racket-repl-mode-hook 'racket-repl-evil-hook)
  361. (defun racket-repl-evil-hook ()
  362. (define-key racket-repl-mode-map "\C-w" 'evil-window-map)
  363. (global-set-key (kbd "C-w") 'racket-repl-mode-map)))
  364. (use-package editorconfig
  365. :diminish editorconfig-mode
  366. :config
  367. (editorconfig-mode 1))
  368. (use-package ivy
  369. :diminish ivy-mode
  370. :config
  371. (ivy-mode))
  372. (use-package flx
  373. :config
  374. (setq ivy-re-builders-alist '((t . ivy--regex-fuzzy))))
  375. (use-package company
  376. :diminish company-mode)
  377. (use-package flycheck
  378. :diminish flycheck-mode
  379. :config
  380. (add-hook 'after-init-hook #'global-flycheck-mode)
  381. (setq flycheck-check-syntax-automatically '(save mode-enabled))
  382. (setq flycheck-checkers (delq 'emacs-lisp-checkdoc flycheck-checkers))
  383. (setq flycheck-checkers (delq 'html-tidy flycheck-checkers))
  384. (setq flycheck-standard-error-navigation nil)
  385. (global-flycheck-mode t))
  386. (use-package flycheck-pos-tip
  387. :after flycheck
  388. :config
  389. (flycheck-pos-tip-mode))
  390. (use-package evil-surround
  391. :config
  392. (global-evil-surround-mode 1))
  393. (use-package dtrt-indent
  394. :diminish dtrt-indent-mode
  395. :config
  396. (dtrt-indent-mode 1))
  397. (use-package org)
  398. ;;;; System-specific configs
  399. (defun win-setup ()
  400. (add-to-list 'exec-path "C:/Program Files (x86)/Aspell/bin/")
  401. (setq ispell-program-name "aspell")
  402. (defun cmd ()
  403. (interactive)
  404. (make-comint-in-buffer "cmd" nil "cmd" nil)
  405. (switch-to-buffer "*cmd*")))
  406. (defun linux-setup ())
  407. (cond ((eq system-type 'windows-nt) (win-setup))
  408. ((eq system-type 'gnu/linux) (linux-setup))
  409. (t (message "")))
  410. ;;;; Custom
  411. (defconst custom-file (expand-file-name "custom.el" user-emacs-directory))
  412. ;; if no custom file exists, write a default one
  413. (unless (file-exists-p custom-file)
  414. (write-region "(custom-set-faces
  415. ;; custom-set-faces was added by Custom.
  416. ;; If you edit it by hand, you could mess it up, so be careful.
  417. ;; Your init file should contain only one such instance.
  418. ;; If there is more than one, they won't work right.
  419. '(powerline-evil-normal-face ((t (:background \"#859900\")))))
  420. (custom-set-variables
  421. ;; custom-set-variables was added by Custom.
  422. ;; If you edit it by hand, you could mess it up, so be careful.
  423. ;; Your init file should contain only one such instance.
  424. ;; If there is more than one, they won't work right.
  425. '(custom-enabled-themes (quote (monokai)))
  426. '(custom-safe-themes
  427. (quote
  428. (\"c7a9a68bd07e38620a5508fef62ec079d274475c8f92d75ed0c33c45fbe306bc\" default))))
  429. " nil custom-file))
  430. (load custom-file)