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.

364 lines
12 KiB

14 years ago
  1. ;;; prelude-core.el --- Emacs Prelude: core Prelude defuns.
  2. ;;
  3. ;; Copyright (c) 2011 Bozhidar Batsov
  4. ;;
  5. ;; Author: Bozhidar Batsov <bozhidar.batsov@gmail.com>
  6. ;; URL: http://www.emacswiki.org/cgi-bin/wiki/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 'cl)
  29. (require 'thingatpt)
  30. (defun prelude-add-subfolders-to-load-path (parent-dir)
  31. "Adds all first level `parent-dir' subdirs to the
  32. Emacs load path."
  33. (dolist (f (directory-files parent-dir))
  34. (let ((name (concat parent-dir f)))
  35. (when (and (file-directory-p name)
  36. (not (equal f ".."))
  37. (not (equal f ".")))
  38. (add-to-list 'load-path name)))))
  39. ;; add the first level subfolders of vendor automatically
  40. (prelude-add-subfolders-to-load-path prelude-vendor-dir)
  41. (defun prelude-open-with ()
  42. "Simple function that allows us to open the underlying
  43. file of a buffer in an external program."
  44. (interactive)
  45. (when buffer-file-name
  46. (shell-command (concat
  47. (if (eq system-type 'darwin)
  48. "open"
  49. (read-shell-command "Open current file with: "))
  50. " "
  51. buffer-file-name))))
  52. (defun prelude-buffer-mode (buffer-or-name)
  53. (with-current-buffer buffer-or-name major-mode))
  54. (defun prelude-visit-term-buffer ()
  55. (interactive)
  56. (if (not (get-buffer "*ansi-term*"))
  57. (ansi-term "/bin/bash")
  58. (switch-to-buffer "*ansi-term*")))
  59. (defun prelude-google ()
  60. "Googles a query or region if any."
  61. (interactive)
  62. (browse-url
  63. (concat
  64. "http://www.google.com/search?ie=utf-8&oe=utf-8&q="
  65. (if mark-active
  66. (buffer-substring (region-beginning) (region-end))
  67. (read-string "Google: ")))))
  68. (defun prelude-indent-rigidly-and-copy-to-clipboard (begin end indent)
  69. "Copy the selected code region to the clipboard, indented according
  70. to Markdown blockquote rules."
  71. (let ((buffer (current-buffer)))
  72. (with-temp-buffer
  73. (insert-buffer-substring-no-properties buffer begin end)
  74. (indent-rigidly (point-min) (point-max) indent)
  75. (clipboard-kill-ring-save (point-min) (point-max)))))
  76. (defun prelude-indent-blockquote-and-copy-to-clipboard (begin end)
  77. "Copy the selected code region to the clipboard, indented according
  78. to markdown blockquote rules (useful to copy snippets to StackOverflow, Assembla, Github."
  79. (interactive "r")
  80. (prelude-indent-rigidly-and-copy-to-clipboard begin end 4))
  81. (defun prelude-indent-nested-blockquote-and-copy-to-clipboard (begin end)
  82. "Copy the selected code region to the clipboard, indented according
  83. to markdown blockquote rules. Useful to add snippets under bullet points."
  84. (interactive "r")
  85. (prelude-indent-rigidly-and-copy-to-clipboard begin end 6))
  86. (defun prelude-insert-empty-line ()
  87. "Insert an empty line after the current line and positon
  88. the curson at its beginning, according to the current mode."
  89. (interactive)
  90. (move-end-of-line nil)
  91. (open-line 1)
  92. (next-line 1)
  93. (indent-according-to-mode))
  94. (defun prelude-move-line-up ()
  95. "Move up the current line."
  96. (interactive)
  97. (transpose-lines 1)
  98. (previous-line 2))
  99. (defun prelude-move-line-down ()
  100. "Move down the current line."
  101. (interactive)
  102. (next-line 1)
  103. (transpose-lines 1)
  104. (previous-line 1))
  105. ;; add the ability to copy and cut the current line, without marking it
  106. (defadvice kill-ring-save (before slick-copy activate compile)
  107. "When called interactively with no active region, copy a single line instead."
  108. (interactive
  109. (if mark-active (list (region-beginning) (region-end))
  110. (message "Copied line")
  111. (list (line-beginning-position)
  112. (line-beginning-position 2)))))
  113. (defadvice kill-region (before slick-cut activate compile)
  114. "When called interactively with no active region, kill a single line instead."
  115. (interactive
  116. (if mark-active (list (region-beginning) (region-end))
  117. (list (line-beginning-position)
  118. (line-beginning-position 2)))))
  119. (defun prelude-indent-buffer ()
  120. "Indents the entire buffer."
  121. (interactive)
  122. (indent-region (point-min) (point-max)))
  123. (defun prelude-indent-region-or-buffer ()
  124. "Indents a region if selected, otherwise the whole buffer."
  125. (interactive)
  126. (save-excursion
  127. (if (region-active-p)
  128. (progn
  129. (indent-region (region-beginning) (region-end))
  130. (message "Indented selected region."))
  131. (progn
  132. (prelude-indent-buffer)
  133. (message "Indented buffer.")))))
  134. (defun prelude-annotate-todo ()
  135. "Put fringe marker on TODO: lines in the curent buffer."
  136. (interactive)
  137. (save-excursion
  138. (goto-char (point-min))
  139. (while (re-search-forward "TODO:" nil t)
  140. (let ((overlay (make-overlay (- (point) 5) (point))))
  141. (overlay-put overlay
  142. 'before-string
  143. (propertize (format "A")
  144. 'display '(left-fringe right-triangle)))))))
  145. (defun prelude-copy-file-name-to-clipboard ()
  146. "Copy the current buffer file name to the clipboard."
  147. (interactive)
  148. (let ((filename (if (equal major-mode 'dired-mode)
  149. default-directory
  150. (buffer-file-name))))
  151. (when filename
  152. (kill-new filename)
  153. (message "Copied buffer file name '%s' to the clipboard." filename))))
  154. (defun prelude-duplicate-current-line-or-region (arg)
  155. "Duplicates the current line or region ARG times.
  156. If there's no region, the current line will be duplicated. However, if
  157. there's a region, all lines that region covers will be duplicated."
  158. (interactive "p")
  159. (let (beg end (origin (point)))
  160. (if (and mark-active (> (point) (mark)))
  161. (exchange-point-and-mark))
  162. (setq beg (line-beginning-position))
  163. (if mark-active
  164. (exchange-point-and-mark))
  165. (setq end (line-end-position))
  166. (let ((region (buffer-substring-no-properties beg end)))
  167. (dotimes (i arg)
  168. (goto-char end)
  169. (newline)
  170. (insert region)
  171. (setq end (point)))
  172. (goto-char (+ origin (* (length region) arg) arg)))))
  173. ;; TODO doesn't work with uniquify
  174. (defun prelude-rename-file-and-buffer ()
  175. "Renames current buffer and file it is visiting."
  176. (interactive)
  177. (let ((name (buffer-name))
  178. (filename (buffer-file-name)))
  179. (if (not (and filename (file-exists-p filename)))
  180. (message "Buffer '%s' is not visiting a file!" name)
  181. (let ((new-name (read-file-name "New name: " filename)))
  182. (cond ((get-buffer new-name)
  183. (message "A buffer named '%s' already exists!" new-name))
  184. (t
  185. (rename-file name new-name 1)
  186. (rename-buffer new-name)
  187. (set-visited-file-name new-name)
  188. (set-buffer-modified-p nil)))))))
  189. (defun prelude-delete-file-and-buffer ()
  190. "Kills the current buffer and deletes the file it is visiting"
  191. (interactive)
  192. (let ((filename (buffer-file-name)))
  193. (when filename
  194. (delete-file filename)
  195. (message "Deleted file %s" filename)))
  196. (kill-buffer))
  197. (defun prelude-view-url ()
  198. "Open a new buffer containing the contents of URL."
  199. (interactive)
  200. (let* ((default (thing-at-point-url-at-point))
  201. (url (read-from-minibuffer "URL: " default)))
  202. (switch-to-buffer (url-retrieve-synchronously url))
  203. (rename-buffer url t)
  204. ;; TODO: switch to nxml/nxhtml mode
  205. (cond ((search-forward "<?xml" nil t) (xml-mode))
  206. ((search-forward "<html" nil t) (html-mode)))))
  207. ;; We have a number of turn-on-* functions since it's advised that lambda
  208. ;; functions not go in hooks. Repeatedly evaluating an add-to-list with a
  209. ;; hook value will repeatedly add it since there's no way to ensure
  210. ;; that a lambda doesn't already exist in the list.
  211. (defun prelude-turn-on-whitespace ()
  212. (whitespace-mode +1))
  213. (defun prelude-turn-off-whitespace ()
  214. (whitespace-mode -1))
  215. (defun prelude-turn-on-abbrev ()
  216. (abbrev-mode +1))
  217. (defun prelude-turn-off-abbrev ()
  218. (abbrev-mode -1))
  219. (defun prelude-untabify-buffer ()
  220. (interactive)
  221. (untabify (point-min) (point-max)))
  222. (defun prelude-cleanup-buffer ()
  223. "Perform a bunch of operations on the whitespace content of a buffer."
  224. (interactive)
  225. (prelude-indent-buffer)
  226. (prelude-untabify-buffer)
  227. (whitespace-cleanup))
  228. (defun prelude-eval-and-replace ()
  229. "Replace the preceding sexp with its value."
  230. (interactive)
  231. (backward-kill-sexp)
  232. (condition-case nil
  233. (prin1 (eval (read (current-kill 0)))
  234. (current-buffer))
  235. (error (message "Invalid expression")
  236. (insert (current-kill 0)))))
  237. (defun prelude-recompile-init ()
  238. "Byte-compile all your dotfiles again."
  239. (interactive)
  240. (byte-recompile-directory prelude-dir 0)
  241. (byte-recompile-directory prelude-vendor-dir 0))
  242. (defun prelude-regen-autoloads (&optional force-regen)
  243. "Regenerate the autoload definitions file if necessary and load it."
  244. (interactive "P")
  245. (let ((autoload-dir prelude-vendor-dir)
  246. (generated-autoload-file autoload-file))
  247. (when (or force-regen
  248. (not (file-exists-p autoload-file))
  249. (some (lambda (f) (file-newer-than-file-p f autoload-file))
  250. (directory-files autoload-dir t "\\.el$")))
  251. (message "Updating autoloads...")
  252. (let (emacs-lisp-mode-hook)
  253. (update-directory-autoloads autoload-dir))))
  254. (load autoload-file))
  255. (defun prelude-sudo-edit (&optional arg)
  256. (interactive "p")
  257. (if (or arg (not buffer-file-name))
  258. (find-file (concat "/sudo:root@localhost:" (ido-read-file-name "File: ")))
  259. (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))
  260. (defun prelude-switch-or-start (function buffer)
  261. "If the buffer is current, bury it, otherwise invoke the function."
  262. (if (equal (buffer-name (current-buffer)) buffer)
  263. (bury-buffer)
  264. (if (get-buffer buffer)
  265. (switch-to-buffer buffer)
  266. (funcall function))))
  267. (defun prelude-insert-date ()
  268. "Insert a time-stamp according to locale's date and time format."
  269. (interactive)
  270. (insert (format-time-string "%c" (current-time))))
  271. (defun prelude-conditionally-enable-paredit-mode ()
  272. "Enable paredit-mode in the minibuffer, during eval-expression."
  273. (if (eq this-command 'eval-expression)
  274. (paredit-mode 1)))
  275. (add-hook 'minibuffer-setup-hook 'prelude-conditionally-enable-paredit-mode)
  276. (defun prelude-recentf-ido-find-file ()
  277. "Find a recent file using ido."
  278. (interactive)
  279. (let ((file (ido-completing-read "Choose recent file: " recentf-list nil t)))
  280. (when file
  281. (find-file file))))
  282. (defun prelude-swap-windows ()
  283. "If you have 2 windows, it swaps them."
  284. (interactive)
  285. (if (/= (count-windows) 2)
  286. (message "You need exactly 2 windows to do this.")
  287. (let* ((w1 (first (window-list)))
  288. (w2 (second (window-list)))
  289. (b1 (window-buffer w1))
  290. (b2 (window-buffer w2))
  291. (s1 (window-start w1))
  292. (s2 (window-start w2)))
  293. (set-window-buffer w1 b2)
  294. (set-window-buffer w2 b1)
  295. (set-window-start w1 s2)
  296. (set-window-start w2 s1)))
  297. (other-window 1))
  298. (defun prelude-kill-other-buffers ()
  299. "Kill all buffers but the current one. Doesn't mess with special buffers."
  300. (interactive)
  301. (dolist (buffer (buffer-list))
  302. (unless (or (eql buffer (current-buffer)) (not (buffer-file-name buffer)))
  303. (kill-buffer buffer))))
  304. (defun prelude-restore-arrow-keys ()
  305. "Restores arrow keys navigation in buffers."
  306. (interactive)
  307. (global-set-key [up] 'previous-line)
  308. (global-set-key [down] 'next-line)
  309. (global-set-key [left] 'backward-char)
  310. (global-set-key [right] 'forward-char)
  311. (global-set-key [M-right] 'right-word)
  312. (global-set-key [M-left] 'left-word)
  313. (message "Arrow keys navigation in buffers in now allowed."))
  314. (provide 'prelude-core)
  315. ;;; prelude-core.el ends here