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.

331 lines
11 KiB

13 years ago
14 years ago
13 years ago
14 years ago
  1. ;;; prelude-core.el --- Emacs Prelude: Core Prelude functions.
  2. ;;
  3. ;; Copyright © 2011-2013 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. ;; Here are the definitions of most of the functions added by Prelude.
  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. (require 'thingatpt)
  29. (defun prelude-open-with ()
  30. "Open visited file in external program."
  31. (interactive)
  32. (when buffer-file-name
  33. (shell-command (concat
  34. (if (eq system-type 'darwin)
  35. "open"
  36. (read-shell-command "Open current file with: "))
  37. " "
  38. buffer-file-name))))
  39. (defun prelude-buffer-mode (buffer-or-name)
  40. "Retrieve the `major-mode' of BUFFER-OR-NAME."
  41. (with-current-buffer buffer-or-name major-mode))
  42. (defun prelude-visit-term-buffer ()
  43. "Create or visit a terminal buffer."
  44. (interactive)
  45. (if (not (get-buffer "*ansi-term*"))
  46. (progn
  47. (split-window-sensibly (selected-window))
  48. (other-window 1)
  49. (ansi-term (getenv "SHELL")))
  50. (switch-to-buffer-other-window "*ansi-term*")))
  51. (defun prelude-google ()
  52. "Googles a query or region if any."
  53. (interactive)
  54. (browse-url
  55. (concat
  56. "http://www.google.com/search?ie=utf-8&oe=utf-8&q="
  57. (url-hexify-string (if mark-active
  58. (buffer-substring (region-beginning) (region-end))
  59. (read-string "Google: "))))))
  60. (defun prelude-indent-rigidly-and-copy-to-clipboard (begin end arg)
  61. "Indent region between BEGIN and END by ARG columns and copy to clipboard."
  62. (interactive "r\nP")
  63. (let ((arg (or arg 4))
  64. (buffer (current-buffer)))
  65. (with-temp-buffer
  66. (insert-buffer-substring-no-properties buffer begin end)
  67. (indent-rigidly (point-min) (point-max) arg)
  68. (clipboard-kill-ring-save (point-min) (point-max)))))
  69. (defun prelude-insert-empty-line ()
  70. "Insert an empty line after the current line.
  71. Position the cursor at its beginning, according to the current mode."
  72. (interactive)
  73. (move-end-of-line nil)
  74. (open-line 1)
  75. (forward-line 1)
  76. (indent-according-to-mode))
  77. (defun prelude-move-line-up ()
  78. "Move up the current line."
  79. (interactive)
  80. (transpose-lines 1)
  81. (forward-line -2))
  82. (defun prelude-move-line-down ()
  83. "Move down the current line."
  84. (interactive)
  85. (forward-line 1)
  86. (transpose-lines 1)
  87. (forward-line -1))
  88. (defun prelude-indent-buffer ()
  89. "Indent the currently visited buffer."
  90. (interactive)
  91. (indent-region (point-min) (point-max)))
  92. (defun prelude-indent-region-or-buffer ()
  93. "Indent a region if selected, otherwise the whole buffer."
  94. (interactive)
  95. (save-excursion
  96. (if (region-active-p)
  97. (progn
  98. (indent-region (region-beginning) (region-end))
  99. (message "Indented selected region."))
  100. (progn
  101. (prelude-indent-buffer)
  102. (message "Indented buffer.")))))
  103. (defun prelude-annotate-todo ()
  104. "Put fringe marker on TODO: lines in the curent buffer."
  105. (interactive)
  106. (save-excursion
  107. (goto-char (point-min))
  108. (while (re-search-forward "TODO:" nil t)
  109. (let ((overlay (make-overlay (- (point) 5) (point))))
  110. (overlay-put overlay
  111. 'before-string
  112. (propertize (format "A")
  113. 'display '(left-fringe right-triangle)))))))
  114. (defun prelude-copy-file-name-to-clipboard ()
  115. "Copy the current buffer file name to the clipboard."
  116. (interactive)
  117. (let ((filename (if (equal major-mode 'dired-mode)
  118. default-directory
  119. (buffer-file-name))))
  120. (when filename
  121. (kill-new filename)
  122. (message "Copied buffer file name '%s' to the clipboard." filename))))
  123. (defun prelude-duplicate-current-line-or-region (arg)
  124. "Duplicates the current line or region ARG times.
  125. If there's no region, the current line will be duplicated. However, if
  126. there's a region, all lines that region covers will be duplicated."
  127. (interactive "p")
  128. (let (beg end (origin (point)))
  129. (if (and mark-active (> (point) (mark)))
  130. (exchange-point-and-mark))
  131. (setq beg (line-beginning-position))
  132. (if mark-active
  133. (exchange-point-and-mark))
  134. (setq end (line-end-position))
  135. (let ((region (buffer-substring-no-properties beg end)))
  136. (-dotimes arg
  137. (lambda (n)
  138. (goto-char end)
  139. (newline)
  140. (insert region)
  141. (setq end (point))))
  142. (goto-char (+ origin (* (length region) arg) arg)))))
  143. ;; TODO doesn't work with uniquify
  144. (defun prelude-rename-file-and-buffer ()
  145. "Renames current buffer and file it is visiting."
  146. (interactive)
  147. (let ((name (buffer-name))
  148. (filename (buffer-file-name)))
  149. (if (not (and filename (file-exists-p filename)))
  150. (message "Buffer '%s' is not visiting a file!" name)
  151. (let ((new-name (read-file-name "New name: " filename)))
  152. (cond ((get-buffer new-name)
  153. (message "A buffer named '%s' already exists!" new-name))
  154. (t
  155. (rename-file name new-name 1)
  156. (rename-buffer new-name)
  157. (set-visited-file-name new-name)
  158. (set-buffer-modified-p nil)))))))
  159. (defun prelude-delete-file-and-buffer ()
  160. "Kill the current buffer and deletes the file it is visiting."
  161. (interactive)
  162. (let ((filename (buffer-file-name)))
  163. (when filename
  164. (delete-file filename)
  165. (message "Deleted file %s" filename)))
  166. (kill-buffer))
  167. (defun prelude-view-url ()
  168. "Open a new buffer containing the contents of URL."
  169. (interactive)
  170. (let* ((default (thing-at-point-url-at-point))
  171. (url (read-from-minibuffer "URL: " default)))
  172. (switch-to-buffer (url-retrieve-synchronously url))
  173. (rename-buffer url t)
  174. ;; TODO: switch to nxml/nxhtml mode
  175. (cond ((search-forward "<?xml" nil t) (xml-mode))
  176. ((search-forward "<html" nil t) (html-mode)))))
  177. (defun prelude-untabify-buffer ()
  178. "Remove all tabs from the current buffer."
  179. (interactive)
  180. (untabify (point-min) (point-max)))
  181. (defun prelude-cleanup-buffer ()
  182. "Perform a bunch of operations on the whitespace content of a buffer."
  183. (interactive)
  184. (prelude-indent-buffer)
  185. (prelude-untabify-buffer)
  186. (whitespace-cleanup))
  187. (defun prelude-eval-and-replace ()
  188. "Replace the preceding sexp with its value."
  189. (interactive)
  190. (backward-kill-sexp)
  191. (condition-case nil
  192. (prin1 (eval (read (current-kill 0)))
  193. (current-buffer))
  194. (error (message "Invalid expression")
  195. (insert (current-kill 0)))))
  196. (defun prelude-recompile-init ()
  197. "Byte-compile all your dotfiles again."
  198. (interactive)
  199. (byte-recompile-directory prelude-dir 0))
  200. (defun prelude-sudo-edit (&optional arg)
  201. (interactive "p")
  202. (if (or arg (not buffer-file-name))
  203. (find-file (concat "/sudo:root@localhost:" (ido-read-file-name "File: ")))
  204. (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))
  205. (defun prelude-switch-or-start (function buffer)
  206. "If BUFFER is current, bury it, otherwise invoke FUNCTION."
  207. (if (equal (buffer-name (current-buffer)) buffer)
  208. (bury-buffer)
  209. (if (get-buffer buffer)
  210. (switch-to-buffer buffer)
  211. (funcall function))))
  212. (defun prelude-insert-date ()
  213. "Insert a timestamp according to locale's date and time format."
  214. (interactive)
  215. (insert (format-time-string "%c" (current-time))))
  216. (defun prelude-conditionally-enable-paredit-mode ()
  217. "Enable `paredit-mode' in the minibuffer, during `eval-expression'."
  218. (if (eq this-command 'eval-expression)
  219. (paredit-mode 1)))
  220. (add-hook 'minibuffer-setup-hook 'prelude-conditionally-enable-paredit-mode)
  221. (defun prelude-recentf-ido-find-file ()
  222. "Find a recent file using ido."
  223. (interactive)
  224. (let ((file (ido-completing-read "Choose recent file: " recentf-list nil t)))
  225. (when file
  226. (find-file file))))
  227. (defun prelude-swap-windows ()
  228. "If you have 2 windows, it swaps them."
  229. (interactive)
  230. (if (/= (count-windows) 2)
  231. (message "You need exactly 2 windows to do this.")
  232. (let* ((w1 (car (window-list)))
  233. (w2 (cadr (window-list)))
  234. (b1 (window-buffer w1))
  235. (b2 (window-buffer w2))
  236. (s1 (window-start w1))
  237. (s2 (window-start w2)))
  238. (set-window-buffer w1 b2)
  239. (set-window-buffer w2 b1)
  240. (set-window-start w1 s2)
  241. (set-window-start w2 s1)))
  242. (other-window 1))
  243. (defun prelude-kill-other-buffers ()
  244. "Kill all buffers but the current one.
  245. Doesn't mess with special buffers."
  246. (interactive)
  247. (-each
  248. (->> (buffer-list)
  249. (-filter #'buffer-file-name)
  250. (--remove (eql (current-buffer) it)))
  251. #'kill-buffer))
  252. (defun prelude-create-scratch-buffer ()
  253. "Create a new scratch buffer."
  254. (interactive)
  255. (progn
  256. (switch-to-buffer
  257. (get-buffer-create (generate-new-buffer-name "*scratch*")))
  258. (emacs-lisp-mode)))
  259. (defvar prelude-tips
  260. '("Press <C-c o> to open a file with external program."
  261. "Press <C-c p f> to navigate a project's files with ido."
  262. "Press <C-c h> to navigate a project in Helm."
  263. "Press <C-c g> to search in Google."
  264. "Press <C-c r> to rename the current buffer and file it's visiting."
  265. "Press <C-c t> to open a terminal in Emacs."
  266. "Explore the Prelude menu to find out about some of Prelude extensions to Emacs."
  267. "Access the official Emacs manual by pressing <C-h r>."
  268. "Visit WikEmacs at http://wikemacs.org to find out even more about Emacs."))
  269. (defun prelude-tip-of-the-day ()
  270. "Display a random entry from `prelude-tips'."
  271. (interactive)
  272. ;; pick a new random seed
  273. (random t)
  274. (message
  275. (concat "Prelude tip: " (nth (random (length prelude-tips)) prelude-tips))))
  276. (defun prelude-eval-after-init (form)
  277. "Add `(lambda () FORM)' to `after-init-hook'.
  278. If Emacs has already finished initialization, also eval FORM immediately."
  279. (let ((func (list 'lambda nil form)))
  280. (add-hook 'after-init-hook func)
  281. (when after-init-time
  282. (eval form))))
  283. (defun prelude-exchange-point-and-mark ()
  284. "Identical to `exchange-point-and-mark' but will not activate the region."
  285. (interactive)
  286. (exchange-point-and-mark)
  287. (deactivate-mark nil))
  288. (provide 'prelude-core)
  289. ;;; prelude-core.el ends here