Emacs config utilizing prelude as a base
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

440 lines
15 KiB

14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
12 years ago
12 years ago
14 years ago
13 years ago
14 years ago
14 years ago
14 years ago
12 years ago
  1. ;;; prelude-editor.el --- Emacs Prelude: enhanced core editing experience.
  2. ;;
  3. ;; Copyright © 2011-2017 Bozhidar Batsov
  4. ;;
  5. ;; Author: Bozhidar Batsov <bozhidar@batsov.com>
  6. ;; URL: https://github.com/bbatsov/prelude
  7. ;; Version: 1.0.0
  8. ;; Keywords: convenience
  9. ;; This file is not part of GNU Emacs.
  10. ;;; Commentary:
  11. ;; Refinements of the core editing experience in Emacs.
  12. ;;; License:
  13. ;; This program is free software; you can redistribute it and/or
  14. ;; modify it under the terms of the GNU General Public License
  15. ;; as published by the Free Software Foundation; either version 3
  16. ;; of the License, or (at your option) any later version.
  17. ;;
  18. ;; This program is distributed in the hope that it will be useful,
  19. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. ;; GNU General Public License for more details.
  22. ;;
  23. ;; You should have received a copy of the GNU General Public License
  24. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  25. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  26. ;; Boston, MA 02110-1301, USA.
  27. ;;; Code:
  28. ;; Death to the tabs! However, tabs historically indent to the next
  29. ;; 8-character offset; specifying anything else will cause *mass*
  30. ;; confusion, as it will change the appearance of every existing file.
  31. ;; In some cases (python), even worse -- it will change the semantics
  32. ;; (meaning) of the program.
  33. ;;
  34. ;; Emacs modes typically provide a standard means to change the
  35. ;; indentation width -- eg. c-basic-offset: use that to adjust your
  36. ;; personal indentation width, while maintaining the style (and
  37. ;; meaning) of any files you load.
  38. (setq-default indent-tabs-mode nil) ;; don't use tabs to indent
  39. (setq-default tab-width 8) ;; but maintain correct appearance
  40. ;; Newline at end of file
  41. (setq require-final-newline t)
  42. ;; delete the selection with a keypress
  43. (delete-selection-mode t)
  44. ;; store all backup and autosave files in the tmp dir
  45. (setq backup-directory-alist
  46. `((".*" . ,temporary-file-directory)))
  47. (setq auto-save-file-name-transforms
  48. `((".*" ,temporary-file-directory t)))
  49. ;; autosave the undo-tree history
  50. (setq undo-tree-history-directory-alist
  51. `((".*" . ,temporary-file-directory)))
  52. (setq undo-tree-auto-save-history t)
  53. ;; revert buffers automatically when underlying files are changed externally
  54. (global-auto-revert-mode t)
  55. ;; hippie expand is dabbrev expand on steroids
  56. (setq hippie-expand-try-functions-list '(try-expand-dabbrev
  57. try-expand-dabbrev-all-buffers
  58. try-expand-dabbrev-from-kill
  59. try-complete-file-name-partially
  60. try-complete-file-name
  61. try-expand-all-abbrevs
  62. try-expand-list
  63. try-expand-line
  64. try-complete-lisp-symbol-partially
  65. try-complete-lisp-symbol))
  66. ;; smart tab behavior - indent or complete
  67. (setq tab-always-indent 'complete)
  68. ;; smart pairing for all
  69. (require 'smartparens-config)
  70. (setq sp-base-key-bindings 'paredit)
  71. (setq sp-autoskip-closing-pair 'always)
  72. (setq sp-hybrid-kill-entire-symbol nil)
  73. (sp-use-paredit-bindings)
  74. (show-smartparens-global-mode +1)
  75. (define-key prog-mode-map (kbd "M-(") (prelude-wrap-with "("))
  76. ;; FIXME: pick terminal friendly binding
  77. ;; (define-key prog-mode-map (kbd "M-[") (prelude-wrap-with "["))
  78. (define-key prog-mode-map (kbd "M-\"") (prelude-wrap-with "\""))
  79. ;; disable annoying blink-matching-paren
  80. (setq blink-matching-paren nil)
  81. ;; diminish keeps the modeline tidy
  82. (require 'diminish)
  83. ;; meaningful names for buffers with the same name
  84. (require 'uniquify)
  85. (setq uniquify-buffer-name-style 'forward)
  86. (setq uniquify-separator "/")
  87. (setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified
  88. (setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
  89. ;; saveplace remembers your location in a file when saving files
  90. (setq save-place-file (expand-file-name "saveplace" prelude-savefile-dir))
  91. ;; activate it for all buffers
  92. (if (< emacs-major-version 25)
  93. (progn (require 'saveplace)
  94. (setq-default save-place t))
  95. (save-place-mode 1))
  96. ;; savehist keeps track of some history
  97. (require 'savehist)
  98. (setq savehist-additional-variables
  99. ;; search entries
  100. '(search-ring regexp-search-ring)
  101. ;; save every minute
  102. savehist-autosave-interval 60
  103. ;; keep the home clean
  104. savehist-file (expand-file-name "savehist" prelude-savefile-dir))
  105. (savehist-mode +1)
  106. ;; save recent files
  107. (require 'recentf)
  108. (setq recentf-save-file (expand-file-name "recentf" prelude-savefile-dir)
  109. recentf-max-saved-items 500
  110. recentf-max-menu-items 15
  111. ;; disable recentf-cleanup on Emacs start, because it can cause
  112. ;; problems with remote files
  113. recentf-auto-cleanup 'never)
  114. (defun prelude-recentf-exclude-p (file)
  115. "A predicate to decide whether to exclude FILE from recentf."
  116. (let ((file-dir (file-truename (file-name-directory file))))
  117. (-any-p (lambda (dir)
  118. (string-prefix-p dir file-dir))
  119. (mapcar 'file-truename (list prelude-savefile-dir package-user-dir)))))
  120. (add-to-list 'recentf-exclude 'prelude-recentf-exclude-p)
  121. (recentf-mode +1)
  122. ;; use shift + arrow keys to switch between visible buffers
  123. (require 'windmove)
  124. (windmove-default-keybindings)
  125. ;; automatically save buffers associated with files on buffer switch
  126. ;; and on windows switch
  127. (defun prelude-auto-save-command ()
  128. "Save the current buffer if `prelude-auto-save' is not nil."
  129. (when (and prelude-auto-save
  130. buffer-file-name
  131. (buffer-modified-p (current-buffer))
  132. (file-writable-p buffer-file-name))
  133. (save-buffer)))
  134. (defmacro advise-commands (advice-name commands class &rest body)
  135. "Apply advice named ADVICE-NAME to multiple COMMANDS.
  136. The body of the advice is in BODY."
  137. `(progn
  138. ,@(mapcar (lambda (command)
  139. `(defadvice ,command (,class ,(intern (concat (symbol-name command) "-" advice-name)) activate)
  140. ,@body))
  141. commands)))
  142. ;; advise all window switching functions
  143. (advise-commands "auto-save"
  144. (switch-to-buffer other-window windmove-up windmove-down windmove-left windmove-right)
  145. before
  146. (prelude-auto-save-command))
  147. (add-hook 'mouse-leave-buffer-hook 'prelude-auto-save-command)
  148. (when (version<= "24.4" emacs-version)
  149. (add-hook 'focus-out-hook 'prelude-auto-save-command))
  150. (defadvice set-buffer-major-mode (after set-major-mode activate compile)
  151. "Set buffer major mode according to `auto-mode-alist'."
  152. (let* ((name (buffer-name buffer))
  153. (mode (assoc-default name auto-mode-alist 'string-match)))
  154. (when (and mode (consp mode))
  155. (setq mode (car mode)))
  156. (with-current-buffer buffer (if mode (funcall mode)))))
  157. ;; highlight the current line
  158. (global-hl-line-mode +1)
  159. (require 'volatile-highlights)
  160. (volatile-highlights-mode t)
  161. (diminish 'volatile-highlights-mode)
  162. ;; note - this should be after volatile-highlights is required
  163. ;; add the ability to cut the current line, without marking it
  164. (require 'rect)
  165. (crux-with-region-or-line kill-region)
  166. ;; tramp, for sudo access
  167. (require 'tramp)
  168. ;; keep in mind known issues with zsh - see emacs wiki
  169. (setq tramp-default-method "ssh")
  170. (set-default 'imenu-auto-rescan t)
  171. ;; flyspell-mode does spell-checking on the fly as you type
  172. (require 'flyspell)
  173. (setq ispell-program-name "aspell" ; use aspell instead of ispell
  174. ispell-extra-args '("--sug-mode=ultra"))
  175. (defun prelude-enable-flyspell ()
  176. "Enable command `flyspell-mode' if `prelude-flyspell' is not nil."
  177. (when (and prelude-flyspell (executable-find ispell-program-name))
  178. (flyspell-mode +1)))
  179. (defun prelude-cleanup-maybe ()
  180. "Invoke `whitespace-cleanup' if `prelude-clean-whitespace-on-save' is not nil."
  181. (when prelude-clean-whitespace-on-save
  182. (whitespace-cleanup)))
  183. (defun prelude-enable-whitespace ()
  184. "Enable `whitespace-mode' if `prelude-whitespace' is not nil."
  185. (when prelude-whitespace
  186. ;; keep the whitespace decent all the time (in this buffer)
  187. (add-hook 'before-save-hook 'prelude-cleanup-maybe nil t)
  188. (whitespace-mode +1)))
  189. (add-hook 'text-mode-hook 'prelude-enable-flyspell)
  190. (add-hook 'text-mode-hook 'prelude-enable-whitespace)
  191. ;; enable narrowing commands
  192. (put 'narrow-to-region 'disabled nil)
  193. (put 'narrow-to-page 'disabled nil)
  194. (put 'narrow-to-defun 'disabled nil)
  195. ;; enabled change region case commands
  196. (put 'upcase-region 'disabled nil)
  197. (put 'downcase-region 'disabled nil)
  198. ;; enable erase-buffer command
  199. (put 'erase-buffer 'disabled nil)
  200. (require 'expand-region)
  201. ;; bookmarks
  202. (require 'bookmark)
  203. (setq bookmark-default-file (expand-file-name "bookmarks" prelude-savefile-dir)
  204. bookmark-save-flag 1)
  205. ;; projectile is a project management mode
  206. (require 'projectile)
  207. (setq projectile-cache-file (expand-file-name "projectile.cache" prelude-savefile-dir))
  208. (projectile-global-mode t)
  209. ;; avy allows us to effectively navigate to visible things
  210. (require 'avy)
  211. (setq avy-background t)
  212. (setq avy-style 'at-full)
  213. ;; anzu-mode enhances isearch & query-replace by showing total matches and current match position
  214. (require 'anzu)
  215. (diminish 'anzu-mode)
  216. (global-anzu-mode)
  217. (global-set-key (kbd "M-%") 'anzu-query-replace)
  218. (global-set-key (kbd "C-M-%") 'anzu-query-replace-regexp)
  219. ;; dired - reuse current buffer by pressing 'a'
  220. (put 'dired-find-alternate-file 'disabled nil)
  221. ;; always delete and copy recursively
  222. (setq dired-recursive-deletes 'always)
  223. (setq dired-recursive-copies 'always)
  224. ;; if there is a dired buffer displayed in the next window, use its
  225. ;; current subdir, instead of the current subdir of this dired buffer
  226. (setq dired-dwim-target t)
  227. ;; enable some really cool extensions like C-x C-j(dired-jump)
  228. (require 'dired-x)
  229. ;; ediff - don't start another frame
  230. (require 'ediff)
  231. (setq ediff-window-setup-function 'ediff-setup-windows-plain)
  232. ;; clean up obsolete buffers automatically
  233. (require 'midnight)
  234. ;; smarter kill-ring navigation
  235. (require 'browse-kill-ring)
  236. (browse-kill-ring-default-keybindings)
  237. (global-set-key (kbd "s-y") 'browse-kill-ring)
  238. (defadvice exchange-point-and-mark (before deactivate-mark activate compile)
  239. "When called with no active region, do not activate mark."
  240. (interactive
  241. (list (not (region-active-p)))))
  242. (require 'tabify)
  243. (defmacro with-region-or-buffer (func)
  244. "When called with no active region, call FUNC on current buffer."
  245. `(defadvice ,func (before with-region-or-buffer activate compile)
  246. (interactive
  247. (if mark-active
  248. (list (region-beginning) (region-end))
  249. (list (point-min) (point-max))))))
  250. (with-region-or-buffer indent-region)
  251. (with-region-or-buffer untabify)
  252. ;; automatically indenting yanked text if in programming-modes
  253. (defun yank-advised-indent-function (beg end)
  254. "Do indentation, as long as the region isn't too large."
  255. (if (<= (- end beg) prelude-yank-indent-threshold)
  256. (indent-region beg end nil)))
  257. (advise-commands "indent" (yank yank-pop) after
  258. "If current mode is one of `prelude-yank-indent-modes',
  259. indent yanked text (with prefix arg don't indent)."
  260. (if (and (not (ad-get-arg 0))
  261. (not (member major-mode prelude-indent-sensitive-modes))
  262. (or (derived-mode-p 'prog-mode)
  263. (member major-mode prelude-yank-indent-modes)))
  264. (let ((transient-mark-mode nil))
  265. (yank-advised-indent-function (region-beginning) (region-end)))))
  266. ;; abbrev config
  267. (add-hook 'text-mode-hook 'abbrev-mode)
  268. ;; make a shell script executable automatically on save
  269. (add-hook 'after-save-hook
  270. 'executable-make-buffer-file-executable-if-script-p)
  271. ;; .zsh file is shell script too
  272. (add-to-list 'auto-mode-alist '("\\.zsh\\'" . shell-script-mode))
  273. ;; whitespace-mode config
  274. (require 'whitespace)
  275. (setq whitespace-line-column 80) ;; limit line length
  276. (setq whitespace-style '(face tabs empty trailing lines-tail))
  277. ;; saner regex syntax
  278. (require 're-builder)
  279. (setq reb-re-syntax 'string)
  280. (require 'eshell)
  281. (setq eshell-directory-name (expand-file-name "eshell" prelude-savefile-dir))
  282. (setq semanticdb-default-save-directory
  283. (expand-file-name "semanticdb" prelude-savefile-dir))
  284. ;; Compilation from Emacs
  285. (defun prelude-colorize-compilation-buffer ()
  286. "Colorize a compilation mode buffer."
  287. (interactive)
  288. ;; we don't want to mess with child modes such as grep-mode, ack, ag, etc
  289. (when (eq major-mode 'compilation-mode)
  290. (let ((inhibit-read-only t))
  291. (ansi-color-apply-on-region (point-min) (point-max)))))
  292. (require 'compile)
  293. (setq compilation-ask-about-save nil ; Just save before compiling
  294. compilation-always-kill t ; Just kill old compile processes before
  295. ; starting the new one
  296. compilation-scroll-output 'first-error ; Automatically scroll to first
  297. ; error
  298. )
  299. ;; Colorize output of Compilation Mode, see
  300. ;; http://stackoverflow.com/a/3072831/355252
  301. (require 'ansi-color)
  302. (add-hook 'compilation-filter-hook #'prelude-colorize-compilation-buffer)
  303. ;; enable Prelude's keybindings
  304. (prelude-global-mode t)
  305. ;; sensible undo
  306. (global-undo-tree-mode)
  307. (diminish 'undo-tree-mode)
  308. ;; enable winner-mode to manage window configurations
  309. (winner-mode +1)
  310. ;; diff-hl
  311. (global-diff-hl-mode +1)
  312. (add-hook 'dired-mode-hook 'diff-hl-dired-mode)
  313. (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
  314. ;; easy-kill
  315. (global-set-key [remap kill-ring-save] 'easy-kill)
  316. (global-set-key [remap mark-sexp] 'easy-mark)
  317. ;; operate-on-number
  318. (require 'operate-on-number)
  319. (require 'smartrep)
  320. (smartrep-define-key global-map "C-c ."
  321. '(("+" . apply-operation-to-number-at-point)
  322. ("-" . apply-operation-to-number-at-point)
  323. ("*" . apply-operation-to-number-at-point)
  324. ("/" . apply-operation-to-number-at-point)
  325. ("\\" . apply-operation-to-number-at-point)
  326. ("^" . apply-operation-to-number-at-point)
  327. ("<" . apply-operation-to-number-at-point)
  328. (">" . apply-operation-to-number-at-point)
  329. ("#" . apply-operation-to-number-at-point)
  330. ("%" . apply-operation-to-number-at-point)
  331. ("'" . operate-on-number-at-point)))
  332. (defadvice server-visit-files (before parse-numbers-in-lines (files proc &optional nowait) activate)
  333. "Open file with emacsclient with cursors positioned on requested line.
  334. Most of console-based utilities prints filename in format
  335. 'filename:linenumber'. So you may wish to open filename in that format.
  336. Just call:
  337. emacsclient filename:linenumber
  338. and file 'filename' will be opened and cursor set on line 'linenumber'"
  339. (ad-set-arg 0
  340. (mapcar (lambda (fn)
  341. (let ((name (car fn)))
  342. (if (string-match "^\\(.*?\\):\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?$" name)
  343. (cons
  344. (match-string 1 name)
  345. (cons (string-to-number (match-string 2 name))
  346. (string-to-number (or (match-string 3 name) ""))))
  347. fn))) files)))
  348. ;; use settings from .editorconfig file when present
  349. (require 'editorconfig)
  350. (editorconfig-mode 1)
  351. (provide 'prelude-editor)
  352. ;;; prelude-editor.el ends here