init.el 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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. :config
  79. (color-theme-initialize)
  80. (load-theme 'Thomas-Experiement t))
  81. ;; ---------- Use X11 clipboard -----------
  82. (use-package xclip
  83. :if (executable-find "xclip")
  84. :config
  85. (add-to-list 'load-path "~/.emacs.d/elpa/xclip-1.4/")
  86. (xclip-mode 1))
  87. ;; --------- Parentheses Matching ---------
  88. (show-paren-mode)
  89. (use-package highlight-parentheses
  90. :config
  91. (define-globalized-minor-mode global-highlight-parentheses-mode
  92. highlight-parentheses-mode
  93. (lambda ()
  94. (highlight-parentheses-mode t)))
  95. (global-highlight-parentheses-mode t))
  96. (if (version<= "24.4" emacs-version)
  97. (electric-pair-mode)
  98. (use-package autopair
  99. :config
  100. (autopair-global-mode)))
  101. ;; ------------ xTerm Mouse ------------
  102. ;; Disable because it became annoying, sounds cool though.
  103. (use-package mouse
  104. :disabled
  105. :config
  106. (xterm-mouse-mode t))
  107. ;; ----------- Ensime -----------
  108. ;; Java/Scala featues. Includes:
  109. ;; * Inferred types
  110. ;; * Autocomplete
  111. ;; * Syntax highlighting
  112. ;; * Jump to source/docs
  113. ;; * Refactoring
  114. ;; * Error detection
  115. (use-package company)
  116. (if (version<= "24.4" emacs-version)
  117. (use-package ensime
  118. :requires company
  119. :hook (scala-mode java-mode)
  120. :config
  121. (setq ensime-startup-notification nil)
  122. (eval-after-load 'ensime-mode
  123. '(define-key ensime-mode-map (kbd "C-c i")
  124. (lambda () "Generate ensime.sbt file"
  125. (interactive)
  126. (write-region "ensimeScalaVersion in ThisBuild := \"2.11.8\""
  127. nil (concat (read-directory-name "SBT Root:") "ensime.sbt"))))))
  128. (use-package scala-mode
  129. :commands (scala-mode)))
  130. ;; --------- C Syntax checker ---------
  131. ;; TODO: C autocomplete. Both with clang integration and backup naive method
  132. ;; (use-package irony
  133. ;; ;;:hook (c-mode c++-mode objc-mode)
  134. ;; :init
  135. ;; (add-hook 'c++-mode-hook 'irony-mode)
  136. ;; (add-hook 'c-mode-hook 'irony-mode)
  137. ;; (add-hook 'objc-mode-hook 'irony-mode)
  138. ;; :commands (irony-mode irony-version)
  139. ;; :config
  140. ;; (defun my-irony-mode-hook ()
  141. ;; (define-key irony-mode-map [remap completion-at-point]
  142. ;; 'irony-completion-at-point-async)
  143. ;; (define-key irony-mode-map [remap complete-symbol]
  144. ;; 'irony-completion-at-point-async))
  145. ;; (add-hook 'irony-mode-hook 'my-irony-mode-hook)
  146. ;; (add-hook 'irony-mode-hook irony-cdb-autosetup-compile-options)
  147. ;; )
  148. ;; (use-package company
  149. ;; :init (add-hook 'after-init-hook 'global-company-mode)
  150. ;; :config
  151. ;; (setq company-idle-delay nil
  152. ;; company-minimum-prefix-length 2
  153. ;; company-show-numbers t
  154. ;; company-tooltip-limit 20
  155. ;; company-dabbrev-downcase nil
  156. ;; company-backends '((company-irony company-gtags))
  157. ;; )
  158. ;; :bind ("C-;" . company-complete-common)
  159. ;; )
  160. ;; (use-package company-irony
  161. ;; :requires company)
  162. ;; (use-package flycheck-irony
  163. ;; :hook c-mode)
  164. ;; ; :mode ("\\.c\\'" "\\.h\\'")
  165. ;; ------------ Web Mode ------------
  166. (defun my-sgml-insert-gt ()
  167. "Inserts a `>' character and calls
  168. `my-sgml-close-tag-if-necessary', leaving point where it is."
  169. (interactive)
  170. (insert ">")
  171. (save-excursion (my-sgml-close-tag-if-necessary)))
  172. (defun my-sgml-close-tag-if-necessary ()
  173. "Calls sgml-close-tag if the tag immediately before point is
  174. an opening tag that is not followed by a matching closing tag."
  175. (when (looking-back "<\\s-*\\([^</> \t\r\n]+\\)[^</>]*>")
  176. (let ((tag (match-string 1)))
  177. (unless (and (not (sgml-unclosed-tag-p tag))
  178. (looking-at (concat "\\s-*<\\s-*/\\s-*" tag "\\s-*>")))
  179. (sgml-close-tag)))))
  180. ;; TODO: Disable autopair in HTML. Interferes with autoclose tab.
  181. (use-package multi-web-mode
  182. :init
  183. (setq mweb-default-major-mode 'html-mode
  184. mweb-tags '((php-mode "<\\?php\\|<\\? \\|<\\?=" "\\?>")
  185. (js-mode "<script[^>]*>" "</script>")
  186. (css-mode "<style[^>]*>" "</style>"))
  187. mweb-filename-extensions '("php" "htm" "html" "ctp" "phtml" "php4" "php5"))
  188. :config
  189. (multi-web-global-mode 1)
  190. (eval-after-load "sgml-mode"
  191. '(define-key sgml-mode-map ">" 'my-sgml-insert-gt)))
  192. ;; ------------ Git Mode ------------
  193. ;; TODO: make resolving merge conflicts hotkeys not use "^"
  194. ;; TODO: Conflict resolution theme is unreadable
  195. (when (version<= "24.4" emacs-version)
  196. (use-package magit
  197. :bind ("C-x g" . magit-status)))
  198. ;; ----------- Rust Mode ------------
  199. (use-package rust-mode)
  200. (use-package rust-playground
  201. :requires rust-mode)
  202. (use-package cargo
  203. :after rust-mode)
  204. (use-package flycheck-rust
  205. :after rust-mode)
  206. ;; ----------- i3 Support ----------
  207. (use-package i3wm
  208. :disabled
  209. :if (equal (getenv "DESKTOP_SESSION") "i3"))
  210. ;; --------- Racket Mode ----------
  211. (use-package racket-mode)
  212. ;; ---------- C# Mode -------------
  213. (use-package csharp-mode
  214. :if (version<= "24.4" emacs-version))
  215. ;; ------- Markdown Mode ----------
  216. (when (version<= "24.4" emacs-version)
  217. (use-package markdown-mode))
  218. ;; ---- StackOverflow Client ------
  219. (use-package sx
  220. ;; TODO: More keybindings if useful
  221. :bind (("C-c C-q" . sx-search))
  222. :config
  223. (defvar sx-dir (concat user-emacs-directory ".sx"))
  224. (if (file-exists-p sx-dir)
  225. (and (shell-command (concat "chmod 700 " sx-dir))
  226. (shell-command (concat "chmod 600 " sx-dir "/*.el")))
  227. )
  228. :commands (sx-accept
  229. sx-answer
  230. sx-ask
  231. sx-authenticate
  232. sx-bug-report
  233. sx-button-copy
  234. sx-button-edit-this
  235. sx-button-follow-link
  236. sx-cache-invalidate-all
  237. sx-comment
  238. sx-compose-insert-tags
  239. sx-compose-mode
  240. sx-compose-quit
  241. sx-compose-send
  242. sx-delete
  243. sx-display
  244. sx-display-question
  245. sx-downvote
  246. sx-edit
  247. sx-favorite
  248. sx-inbox
  249. sx-inbox-mode
  250. sx-inbox-notifications
  251. sx-open-link
  252. sx-question-list-hide
  253. sx-question-list-mark-read
  254. sx-question-list-mode
  255. sx-question-list-next
  256. sx-question-list-next-far
  257. sx-question-list-next-page
  258. sx-question-list-order-by
  259. sx-question-list-previous
  260. sx-question-list-previous-far
  261. sx-question-list-refresh
  262. sx-question-list-switch-site
  263. sx-question-list-view-next
  264. sx-question-list-view-previous
  265. sx-question-mode
  266. sx-question-mode-hide-show-section
  267. sx-question-mode-next-section
  268. sx-question-mode-order-by
  269. sx-question-mode-previous-section
  270. sx-question-mode-refresh
  271. sx-search
  272. sx-search-tag-at-point
  273. sx-star
  274. sx-tab-all-questions
  275. sx-tab-featured
  276. sx-tab-frontpage
  277. sx-tab-hot
  278. sx-tab-month
  279. sx-tab-newest
  280. sx-tab-starred
  281. sx-tab-topvoted
  282. sx-tab-unanswered
  283. sx-tab-unanswered-my-tags
  284. sx-tab-week
  285. sx-upvote
  286. sx-version
  287. sx-visit-externally))
  288. ;; -------- Spellcheck ------------
  289. (defun flyspell-detect-ispell-args (&optional run-together)
  290. (cond ((string-match "aspell$" ispell-program-name)
  291. (append (list "--sug-mode=ultra" "--lang=en_US")
  292. (if run-together '("--run-together" "--run-together-limit=5" "--run-together-min=2"))))
  293. ((string-match "hunspell$" ispell-program-name)
  294. "-d en_US")))
  295. (use-package flyspell-correct-popup
  296. :bind ("M-s" . ispell-word)
  297. :hook ((text-mode . flyspell-mode)
  298. (prog-mode . flyspell-prog-mode)
  299. ((flyspell-mode flyspell-prog-mode) . flyspell-buffer))
  300. :config
  301. (cond
  302. ((executable-find "aspell")
  303. (setq ispell-program-name "aspell"))
  304. ((executable-find "hunspell")
  305. (setq ispell-program-name "hunspell")
  306. (setq ispell-local-dictionary "en_US")
  307. (setq ispell-local-dictionary-alist
  308. '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8))))
  309. (t
  310. (setq ispell-program-name nil)))
  311. (setq-default ispell-extra-args (flyspell-detect-ispell-args t))
  312. (setq-default flyspell-issue-message-flag nil))
  313. ;; -------- REST Client ---------
  314. (use-package restclient
  315. :commands (restclient-copy-curl-command
  316. restclient-http-send-current
  317. restclient-http-send-current-raw
  318. restclient-http-send-current-stay-in-window
  319. restclient-jump-next
  320. restclient-jump-prev
  321. restclient-mark-current
  322. restclient-mode
  323. restclient-narrow-to-current
  324. restclient-outline-mode
  325. restclient-toggle-body-visibility
  326. restclient-toggle-body-visibility-or-indent))
  327. ;; ------- Highlight TODO -------
  328. ;; Remove transpose bindings. I don't have any reasonable use for them
  329. ;; and would much rather use them for navigating TODO's.
  330. (let ((trans-chars "\C-t");; Transpose (swap) adjacent characters
  331. )
  332. (global-unset-key trans-chars))
  333. (use-package hl-todo
  334. :commands (hl-todo-mode
  335. hl-todo-next
  336. hl-todo-occur
  337. hl-todo-previous)
  338. :hook (prog-mode . hl-todo-mode)
  339. :bind (("C-t n" . hl-todo-next)
  340. ("C-t p" . hl-todo-previous)))
  341. ;; ---- Printer Integration -----
  342. (use-package printing
  343. :bind ("M-p" . print-buffer)
  344. :commands (print-buffer
  345. print-region
  346. lpr-buffer
  347. lpr-customize
  348. lpr-region)
  349. :config
  350. (pr-update-menus t))