;;; prelude-core.el --- Emacs Prelude: core Prelude defuns. ;; ;; Copyright (c) 2011 Bozhidar Batsov ;; ;; Author: Bozhidar Batsov ;; URL: http://www.emacswiki.org/cgi-bin/wiki/Prelude ;; Version: 1.0.0 ;; Keywords: convenience ;; This file is not part of GNU Emacs. ;;; Commentary: ;; Here are the definitions of most of the functions added by Prelude. ;;; License: ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 3 ;; of the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Code: (require 'cl) (require 'thingatpt) (defun prelude-add-subfolders-to-load-path (parent-dir) "Adds all first level `parent-dir' subdirs to the Emacs load path." (dolist (f (directory-files parent-dir)) (let ((name (concat parent-dir f))) (when (and (file-directory-p name) (not (equal f "..")) (not (equal f "."))) (add-to-list 'load-path name))))) ;; add the first level subfolders of vendor automatically (prelude-add-subfolders-to-load-path prelude-vendor-dir) (defun prelude-open-with () "Simple function that allows us to open the underlying file of a buffer in an external program." (interactive) (when buffer-file-name (shell-command (concat (if (eq system-type 'darwin) "open" (read-shell-command "Open current file with: ")) " " buffer-file-name)))) (defun prelude-buffer-mode (buffer-or-name) (with-current-buffer buffer-or-name major-mode)) (defun prelude-visit-term-buffer () (interactive) (if (not (get-buffer "*ansi-term*")) (ansi-term "/bin/bash") (switch-to-buffer "*ansi-term*"))) (defun prelude-google () "Googles a query or region if any." (interactive) (browse-url (concat "http://www.google.com/search?ie=utf-8&oe=utf-8&q=" (url-hexify-string (if mark-active (buffer-substring (region-beginning) (region-end)) (read-string "Google: ")))))) (defun prelude-indent-rigidly-and-copy-to-clipboard (begin end indent) "Copy the selected code region to the clipboard, indented according to Markdown blockquote rules." (let ((buffer (current-buffer))) (with-temp-buffer (insert-buffer-substring-no-properties buffer begin end) (indent-rigidly (point-min) (point-max) indent) (clipboard-kill-ring-save (point-min) (point-max))))) (defun prelude-indent-blockquote-and-copy-to-clipboard (begin end) "Copy the selected code region to the clipboard, indented according to markdown blockquote rules (useful to copy snippets to StackOverflow, Assembla, Github." (interactive "r") (prelude-indent-rigidly-and-copy-to-clipboard begin end 4)) (defun prelude-indent-nested-blockquote-and-copy-to-clipboard (begin end) "Copy the selected code region to the clipboard, indented according to markdown blockquote rules. Useful to add snippets under bullet points." (interactive "r") (prelude-indent-rigidly-and-copy-to-clipboard begin end 6)) (defun prelude-insert-empty-line () "Insert an empty line after the current line and positon the curson at its beginning, according to the current mode." (interactive) (move-end-of-line nil) (open-line 1) (next-line 1) (indent-according-to-mode)) (defun prelude-move-line-up () "Move up the current line." (interactive) (transpose-lines 1) (previous-line 2)) (defun prelude-move-line-down () "Move down the current line." (interactive) (next-line 1) (transpose-lines 1) (previous-line 1)) ;; add the ability to copy and cut the current line, without marking it (defadvice kill-ring-save (before slick-copy activate compile) "When called interactively with no active region, copy a single line instead." (interactive (if mark-active (list (region-beginning) (region-end)) (message "Copied line") (list (line-beginning-position) (line-beginning-position 2))))) (defadvice kill-region (before slick-cut activate compile) "When called interactively with no active region, kill a single line instead." (interactive (if mark-active (list (region-beginning) (region-end)) (list (line-beginning-position) (line-beginning-position 2))))) (defun prelude-indent-buffer () "Indents the entire buffer." (interactive) (indent-region (point-min) (point-max))) (defun prelude-indent-region-or-buffer () "Indents a region if selected, otherwise the whole buffer." (interactive) (save-excursion (if (region-active-p) (progn (indent-region (region-beginning) (region-end)) (message "Indented selected region.")) (progn (prelude-indent-buffer) (message "Indented buffer."))))) (defun prelude-annotate-todo () "Put fringe marker on TODO: lines in the curent buffer." (interactive) (save-excursion (goto-char (point-min)) (while (re-search-forward "TODO:" nil t) (let ((overlay (make-overlay (- (point) 5) (point)))) (overlay-put overlay 'before-string (propertize (format "A") 'display '(left-fringe right-triangle))))))) (defun prelude-copy-file-name-to-clipboard () "Copy the current buffer file name to the clipboard." (interactive) (let ((filename (if (equal major-mode 'dired-mode) default-directory (buffer-file-name)))) (when filename (kill-new filename) (message "Copied buffer file name '%s' to the clipboard." filename)))) (defun prelude-duplicate-current-line-or-region (arg) "Duplicates the current line or region ARG times. If there's no region, the current line will be duplicated. However, if there's a region, all lines that region covers will be duplicated." (interactive "p") (let (beg end (origin (point))) (if (and mark-active (> (point) (mark))) (exchange-point-and-mark)) (setq beg (line-beginning-position)) (if mark-active (exchange-point-and-mark)) (setq end (line-end-position)) (let ((region (buffer-substring-no-properties beg end))) (dotimes (i arg) (goto-char end) (newline) (insert region) (setq end (point))) (goto-char (+ origin (* (length region) arg) arg))))) ;; TODO doesn't work with uniquify (defun prelude-rename-file-and-buffer () "Renames current buffer and file it is visiting." (interactive) (let ((name (buffer-name)) (filename (buffer-file-name))) (if (not (and filename (file-exists-p filename))) (message "Buffer '%s' is not visiting a file!" name) (let ((new-name (read-file-name "New name: " filename))) (cond ((get-buffer new-name) (message "A buffer named '%s' already exists!" new-name)) (t (rename-file name new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil))))))) (defun prelude-delete-file-and-buffer () "Kills the current buffer and deletes the file it is visiting" (interactive) (let ((filename (buffer-file-name))) (when filename (delete-file filename) (message "Deleted file %s" filename))) (kill-buffer)) (defun prelude-view-url () "Open a new buffer containing the contents of URL." (interactive) (let* ((default (thing-at-point-url-at-point)) (url (read-from-minibuffer "URL: " default))) (switch-to-buffer (url-retrieve-synchronously url)) (rename-buffer url t) ;; TODO: switch to nxml/nxhtml mode (cond ((search-forward "