init.el 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. ;; Requires:
  2. ;; aspell
  3. ;; Optional:
  4. ;; clang
  5. ;; TODO
  6. ;; Look up authors of projects. See what other useful things they make.
  7. ;; ----------- Default Variables -----------
  8. ;; Global variables
  9. (defvar backup-directory (concat user-emacs-directory "backups"))
  10. (unless (file-exists-p backup-directory)
  11. (make-directory backup-directory))
  12. (setq-default inhibit-startup-screen t
  13. column-number-mode t
  14. scroll-error-top-bottom t
  15. show-paren-delay 0.25
  16. tab-width 4
  17. indent-tabs-mode nil
  18. ;x-select-enable-clipboard t
  19. ;interprogram-paste-function 'x-cut-buffer-or-selection-value
  20. backup-directory-alist `(("." . ,backup-directory))
  21. delete-old-versions t)
  22. ;; (global-linum-mode)
  23. ;; Delete selected text when typing (normal editor behavior)
  24. (delete-selection-mode t)
  25. ;; ------------- Keybindings -------------
  26. (defun smart-beginning-of-line ()
  27. "Move point to first non-whitespace character or beginning-of-line.
  28. Move point to the first non-whitespace character on this line.
  29. If point was already at that position, move point to beginning of line."
  30. (interactive "^")
  31. ;(if (version< "22" emacs-version) (interactive "^") (interactive))
  32. (let ((oldpos (point)))
  33. (beginning-of-line-text); goes to first significant character
  34. ;(back-to-indentation); goes to first non-whitespace
  35. (and (= oldpos (point))
  36. (beginning-of-line))))
  37. (global-set-key [home] 'smart-beginning-of-line)
  38. (global-set-key (kbd "C-c /") 'comment-or-uncomment-region)
  39. (global-set-key (kbd "C-c C-k") 'compile)
  40. (global-set-key (kbd "M-<left>") 'backward-list)
  41. (global-set-key (kbd "M-<right>") 'forward-list)
  42. (global-set-key (kbd "M-<up>") 'racket-backward-up-list)
  43. ;; Can't seem to find forward-down-list.
  44. ;; Not very important since I would rarely use it anyway
  45. ;;(global-set-key (kbd "M-<down>") '?)
  46. (global-set-key (kbd "M-<delete>") 'kill-sexp)
  47. ;; ----------- Package Managing -----------
  48. ;; The package manager
  49. (require 'package)
  50. ;; Add package sources
  51. (setq package-archives
  52. '(("gnu" . "https://elpa.gnu.org/packages/")
  53. ("melpa" . "https://melpa.org/packages/")
  54. ("melpa-stable" . "https://stable.melpa.org/packages/")
  55. ("org" . "https://orgmode.org/elpa/"))
  56. package-archive-priorities '(("melpa" . 1)))
  57. (package-initialize)
  58. (unless (package-installed-p 'use-package)
  59. (package-refresh-contents)
  60. (package-install 'use-package))
  61. (require 'use-package)
  62. (setq use-package-always-ensure t)
  63. (use-package auto-package-update
  64. :config
  65. (add-hook 'auto-package-update-before-hook
  66. (lambda () (package-refresh-contents)))
  67. (setq auto-package-update-delete-old-versions t
  68. auto-package-update-interval 4
  69. auto-package-update-prompt-before-update t
  70. auto-package-update-hide-results t)
  71. (auto-package-update-maybe))
  72. ;; ---------- Color Themes ----------
  73. ;; TODO: Fix warning underline to always be orange/yellow
  74. ;; Update: Seems it always takes the color of the foreground.
  75. ;; Also seems to ignore most properties. (e.g. overline, underline,
  76. ;; strike-though, etc.) Maybe it's an xterm problem?
  77. (use-package color-theme
  78. :init
  79. ;; TODO: Fixes error about missing directory. Don't know why.
  80. ;(unless (file-exists-p "~/.emacs.d/elpa/color-theme-20070910.1007/themes")
  81. ; (make-directory "~/.emacs.d/elpa/color-theme-20070910.1007/themes"))
  82. :config
  83. (color-theme-initialize)
  84. (load-theme 'Thomas-Experiement t))
  85. ;; ---------- Use X11 clipboard -----------
  86. (use-package xclip
  87. :if (executable-find "xclip")
  88. :config
  89. (add-to-list 'load-path "~/.emacs.d/elpa/xclip-1.4/")
  90. (xclip-mode 1))
  91. ;; --------- Parentheses Matching ---------
  92. (show-paren-mode)
  93. (use-package highlight-parentheses
  94. :config
  95. (define-globalized-minor-mode global-highlight-parentheses-mode
  96. highlight-parentheses-mode
  97. (lambda ()
  98. (highlight-parentheses-mode t)))
  99. (global-highlight-parentheses-mode t))
  100. (if (version<= "24.4" emacs-version)
  101. (electric-pair-mode)
  102. (use-package autopair
  103. :config
  104. (autopair-global-mode)))
  105. ;; ------------ xTerm Mouse ------------
  106. ;; Disable because it became annoying, sounds cool though.
  107. (use-package mouse
  108. :disabled
  109. :config
  110. (xterm-mouse-mode t))
  111. ;; ----------- Ensime -----------
  112. ;; Java/Scala featues. Includes:
  113. ;; * Inferred types
  114. ;; * Autocomplete
  115. ;; * Syntax highlighting
  116. ;; * Jump to source/docs
  117. ;; * Refactoring
  118. ;; * Error detection
  119. (use-package company)
  120. (if (version<= "24.4" emacs-version)
  121. (use-package ensime
  122. :requires company
  123. :hook (scala-mode java-mode)
  124. :config
  125. (setq ensime-startup-notification nil)
  126. (eval-after-load 'ensime-mode
  127. '(define-key ensime-mode-map (kbd "C-c i")
  128. (lambda () "Generate ensime.sbt file"
  129. (interactive)
  130. (write-region "ensimeScalaVersion in ThisBuild := \"2.11.8\""
  131. nil (concat (read-directory-name "SBT Root:") "ensime.sbt"))))))
  132. (use-package scala-mode
  133. :commands (scala-mode)))
  134. ;; --------- C Syntax checker ---------
  135. ;; TODO: C autocomplete. Both with clang integration and backup naive method
  136. ;; (use-package irony
  137. ;; ;;:hook (c-mode c++-mode objc-mode)
  138. ;; :init
  139. ;; (add-hook 'c++-mode-hook 'irony-mode)
  140. ;; (add-hook 'c-mode-hook 'irony-mode)
  141. ;; (add-hook 'objc-mode-hook 'irony-mode)
  142. ;; :commands (irony-mode irony-version)
  143. ;; :config
  144. ;; (defun my-irony-mode-hook ()
  145. ;; (define-key irony-mode-map [remap completion-at-point]
  146. ;; 'irony-completion-at-point-async)
  147. ;; (define-key irony-mode-map [remap complete-symbol]
  148. ;; 'irony-completion-at-point-async))
  149. ;; (add-hook 'irony-mode-hook 'my-irony-mode-hook)
  150. ;; (add-hook 'irony-mode-hook irony-cdb-autosetup-compile-options)
  151. ;; )
  152. ;; (use-package company
  153. ;; :init (add-hook 'after-init-hook 'global-company-mode)
  154. ;; :config
  155. ;; (setq company-idle-delay nil
  156. ;; company-minimum-prefix-length 2
  157. ;; company-show-numbers t
  158. ;; company-tooltip-limit 20
  159. ;; company-dabbrev-downcase nil
  160. ;; company-backends '((company-irony company-gtags))
  161. ;; )
  162. ;; :bind ("C-;" . company-complete-common)
  163. ;; )
  164. ;; (use-package company-irony
  165. ;; :requires company)
  166. ;; (use-package flycheck-irony
  167. ;; :hook c-mode)
  168. ;; ; :mode ("\\.c\\'" "\\.h\\'")
  169. ;; ------------ Web Mode ------------
  170. (defun my-sgml-insert-gt ()
  171. "Inserts a `>' character and calls
  172. `my-sgml-close-tag-if-necessary', leaving point where it is."
  173. (interactive)
  174. (insert ">")
  175. (save-excursion (my-sgml-close-tag-if-necessary)))
  176. (defun my-sgml-close-tag-if-necessary ()
  177. "Calls sgml-close-tag if the tag immediately before point is
  178. an opening tag that is not followed by a matching closing tag."
  179. (when (looking-back "<\\s-*\\([^</> \t\r\n]+\\)[^</>]*>")
  180. (let ((tag (match-string 1)))
  181. (unless (and (not (sgml-unclosed-tag-p tag))
  182. (looking-at (concat "\\s-*<\\s-*/\\s-*" tag "\\s-*>")))
  183. (sgml-close-tag)))))
  184. ;; TODO: Disable autopair in HTML. Interferes with autoclose tab.
  185. (use-package multi-web-mode
  186. :init
  187. (setq mweb-default-major-mode 'html-mode
  188. mweb-tags '((php-mode "<\\?php\\|<\\? \\|<\\?=" "\\?>")
  189. (js-mode "<script[^>]*>" "</script>")
  190. (css-mode "<style[^>]*>" "</style>"))
  191. mweb-filename-extensions '("php" "htm" "html" "ctp" "phtml" "php4" "php5"))
  192. :config
  193. (multi-web-global-mode 1)
  194. (eval-after-load "sgml-mode"
  195. '(define-key sgml-mode-map ">" 'my-sgml-insert-gt)))
  196. ;; ------------ Git Mode ------------
  197. ;; TODO: make resolving merge conflicts hotkeys not use "^"
  198. ;; TODO: Conflict resolution theme is unreadable
  199. (when (version<= "24.4" emacs-version)
  200. (use-package magit
  201. :bind ("C-x g" . magit-status)))
  202. ;; ----------- Rust Mode ------------
  203. (use-package rust-mode)
  204. (use-package rust-playground
  205. :requires rust-mode)
  206. (use-package cargo
  207. :after rust-mode)
  208. (use-package flycheck-rust
  209. :after rust-mode)
  210. ;; ----------- Go Mode -------------
  211. (use-package go-mode)
  212. ;; ----------- i3 Support ----------
  213. (use-package i3wm
  214. :disabled
  215. :if (equal (getenv "DESKTOP_SESSION") "i3"))
  216. ;; --------- Racket Mode ----------
  217. (use-package racket-mode)
  218. ;; ---------- C# Mode -------------
  219. (use-package csharp-mode
  220. :if (version<= "24.4" emacs-version))
  221. ;; ------- Markdown Mode ----------
  222. (when (version<= "24.4" emacs-version)
  223. (use-package markdown-mode))
  224. ;; ---- StackOverflow Client ------
  225. (use-package sx
  226. ;; TODO: More keybindings if useful
  227. :bind (("C-c C-q" . sx-search))
  228. :config
  229. (defvar sx-dir (concat user-emacs-directory ".sx"))
  230. (if (file-exists-p sx-dir)
  231. (and (shell-command (concat "chmod 700 " sx-dir))
  232. (shell-command (concat "chmod 600 " sx-dir "/*.el")))
  233. )
  234. :commands (sx-accept
  235. sx-answer
  236. sx-ask
  237. sx-authenticate
  238. sx-bug-report
  239. sx-button-copy
  240. sx-button-edit-this
  241. sx-button-follow-link
  242. sx-cache-invalidate-all
  243. sx-comment
  244. sx-compose-insert-tags
  245. sx-compose-mode
  246. sx-compose-quit
  247. sx-compose-send
  248. sx-delete
  249. sx-display
  250. sx-display-question
  251. sx-downvote
  252. sx-edit
  253. sx-favorite
  254. sx-inbox
  255. sx-inbox-mode
  256. sx-inbox-notifications
  257. sx-open-link
  258. sx-question-list-hide
  259. sx-question-list-mark-read
  260. sx-question-list-mode
  261. sx-question-list-next
  262. sx-question-list-next-far
  263. sx-question-list-next-page
  264. sx-question-list-order-by
  265. sx-question-list-previous
  266. sx-question-list-previous-far
  267. sx-question-list-refresh
  268. sx-question-list-switch-site
  269. sx-question-list-view-next
  270. sx-question-list-view-previous
  271. sx-question-mode
  272. sx-question-mode-hide-show-section
  273. sx-question-mode-next-section
  274. sx-question-mode-order-by
  275. sx-question-mode-previous-section
  276. sx-question-mode-refresh
  277. sx-search
  278. sx-search-tag-at-point
  279. sx-star
  280. sx-tab-all-questions
  281. sx-tab-featured
  282. sx-tab-frontpage
  283. sx-tab-hot
  284. sx-tab-month
  285. sx-tab-newest
  286. sx-tab-starred
  287. sx-tab-topvoted
  288. sx-tab-unanswered
  289. sx-tab-unanswered-my-tags
  290. sx-tab-week
  291. sx-upvote
  292. sx-version
  293. sx-visit-externally))
  294. ;; -------- Spellcheck ------------
  295. (defun flyspell-detect-ispell-args (&optional run-together)
  296. (cond ((string-match "aspell$" ispell-program-name)
  297. (append (list "--sug-mode=ultra" "--lang=en_US")
  298. (if run-together '("--run-together" "--run-together-limit=5" "--run-together-min=2"))))
  299. ((string-match "hunspell$" ispell-program-name)
  300. "-d en_US")))
  301. (use-package flyspell-correct-popup
  302. :bind ("M-s" . ispell-word)
  303. :hook ((text-mode . flyspell-mode)
  304. (prog-mode . flyspell-prog-mode)
  305. ((flyspell-mode flyspell-prog-mode) . flyspell-buffer))
  306. :config
  307. (cond
  308. ((executable-find "aspell")
  309. (setq ispell-program-name "aspell"))
  310. ((executable-find "hunspell")
  311. (setq ispell-program-name "hunspell")
  312. (setq ispell-local-dictionary "en_US")
  313. (setq ispell-local-dictionary-alist
  314. '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8))))
  315. (t
  316. (setq ispell-program-name nil)))
  317. (setq-default ispell-extra-args (flyspell-detect-ispell-args t))
  318. (setq-default flyspell-issue-message-flag nil))
  319. ;; -------- REST Client ---------
  320. (use-package restclient
  321. :commands (restclient-copy-curl-command
  322. restclient-http-send-current
  323. restclient-http-send-current-raw
  324. restclient-http-send-current-stay-in-window
  325. restclient-jump-next
  326. restclient-jump-prev
  327. restclient-mark-current
  328. restclient-mode
  329. restclient-narrow-to-current
  330. restclient-outline-mode
  331. restclient-toggle-body-visibility
  332. restclient-toggle-body-visibility-or-indent))
  333. ;; ------- Highlight TODO -------
  334. ;; Remove transpose bindings. I don't have any reasonable use for them
  335. ;; and would much rather use them for navigating TODO's.
  336. (let ((trans-chars "\C-t");; Transpose (swap) adjacent characters
  337. )
  338. (global-unset-key trans-chars))
  339. (use-package hl-todo
  340. :commands (hl-todo-mode
  341. hl-todo-next
  342. hl-todo-occur
  343. hl-todo-previous)
  344. :hook (prog-mode . hl-todo-mode)
  345. :bind (("C-t n" . hl-todo-next)
  346. ("C-t p" . hl-todo-previous)))
  347. ;; ---- Printer Integration -----
  348. (use-package printing
  349. :bind ("M-p" . print-buffer)
  350. :commands (print-buffer
  351. print-region
  352. lpr-buffer
  353. lpr-customize
  354. lpr-region)
  355. :config
  356. (pr-update-menus t))