├── init-haml.el ├── init-php.el ├── site-lisp ├── todochiku-icons │ ├── bell.png │ ├── chat.png │ ├── zip.png │ ├── Thumbs.db │ ├── alert.png │ ├── binary.png │ ├── clean.png │ ├── kalarm.png │ ├── kmail.png │ ├── emacs_32.png │ ├── favorites.png │ ├── terminal.png │ ├── groupevent.png │ ├── kbemusedsrv.png │ ├── announcements.png │ └── LICENSE.txt └── nxml-mode │ └── xmltok.el ├── init-crontab.el ├── init-spelling.el ├── init-recentf.el ├── init-erlang.el ├── init-markdown.el ├── init-csv.el ├── init-python-mode.el ├── init-textile.el ├── init-dired.el ├── init-hippie-expand.el ├── init-flycheck.el ├── init-darcs.el ├── init-exec-path.el ├── init-mmm.el ├── .gitignore ├── init-rails.el ├── init-uniquify.el ├── init-osx-keys.el ├── init-misc.el ├── init-sql.el ├── init-frame-hooks.el ├── init-xterm.el ├── init-locales.el ├── init-benchmarking.el ├── init-growl.el ├── init-ido.el ├── init-flyspell.el ├── init-haskell.el ├── init-nxml.el ├── init-proxies.el ├── init-ibuffer.el ├── init-slime.el ├── init-css.el ├── init-common-lisp.el ├── README.md ├── init-site-lisp.el ├── init-fonts.el ├── init-paredit.el ├── init-compat.el ├── init-auto-complete.el ├── init-maxframe.el ├── init-clojure.el ├── init-gui-frames.el ├── init-windows.el ├── init-isearch.el ├── init-sessions.el ├── init-marmalade.el ├── init-elpa.el ├── init-themes.el ├── init-git.el ├── init-javascript.el ├── init-utils.el ├── init-ruby-mode.el ├── init-org.el ├── init.el ├── init-lisp.el └── init-editing-utils.el /init-haml.el: -------------------------------------------------------------------------------- 1 | (require-package 'haml-mode) 2 | 3 | (provide 'init-haml) 4 | -------------------------------------------------------------------------------- /init-php.el: -------------------------------------------------------------------------------- 1 | (require-package 'php-mode) 2 | (require-package 'smarty-mode) 3 | 4 | (provide 'init-php) 5 | -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/bell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/bell.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/chat.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/zip.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/Thumbs.db -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/alert.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/binary.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/clean.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/kalarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/kalarm.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/kmail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/kmail.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/emacs_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/emacs_32.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/favorites.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/terminal.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/groupevent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/groupevent.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/kbemusedsrv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/kbemusedsrv.png -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/announcements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/emacs.d/master/site-lisp/todochiku-icons/announcements.png -------------------------------------------------------------------------------- /init-crontab.el: -------------------------------------------------------------------------------- 1 | (require-package 'crontab-mode) 2 | (add-auto-mode 'crontab-mode "\\.?cron\\(tab\\)?\\'") 3 | 4 | (provide 'init-crontab) 5 | -------------------------------------------------------------------------------- /init-spelling.el: -------------------------------------------------------------------------------- 1 | (require 'ispell) 2 | 3 | (when (executable-find ispell-program-name) 4 | (require 'init-flyspell)) 5 | 6 | (provide 'init-spelling) 7 | -------------------------------------------------------------------------------- /init-recentf.el: -------------------------------------------------------------------------------- 1 | (recentf-mode 1) 2 | (setq recentf-max-saved-items 1000 3 | recentf-exclude '("/tmp/" "/ssh:")) 4 | 5 | 6 | (provide 'init-recentf) 7 | -------------------------------------------------------------------------------- /init-erlang.el: -------------------------------------------------------------------------------- 1 | (ignore-errors 2 | (require-package 'erlang)) 3 | 4 | (when (package-installed-p 'erlang) 5 | (require 'erlang-start)) 6 | 7 | (provide 'init-erlang) 8 | -------------------------------------------------------------------------------- /init-markdown.el: -------------------------------------------------------------------------------- 1 | (require-package 'markdown-mode) 2 | 3 | (setq auto-mode-alist 4 | (cons '("\\.\\(md\\|markdown\\)\\'" . markdown-mode) auto-mode-alist)) 5 | 6 | (provide 'init-markdown) 7 | -------------------------------------------------------------------------------- /init-csv.el: -------------------------------------------------------------------------------- 1 | (require-package 'csv-mode) 2 | (require-package 'csv-nav) 3 | 4 | (add-auto-mode 'csv-mode "\\.[Cc][Ss][Vv]\\'") 5 | 6 | (setq csv-separators '("," ";" "|" " ")) 7 | 8 | (provide 'init-csv) 9 | -------------------------------------------------------------------------------- /init-python-mode.el: -------------------------------------------------------------------------------- 1 | (setq auto-mode-alist 2 | (append '(("SConstruct\\'" . python-mode) 3 | ("SConscript\\'" . python-mode)) 4 | auto-mode-alist)) 5 | 6 | 7 | (provide 'init-python-mode) 8 | -------------------------------------------------------------------------------- /init-textile.el: -------------------------------------------------------------------------------- 1 | (require-package 'textile-mode) 2 | 3 | (autoload 'textile-mode "textile-mode" "Mode for editing Textile documents" t) 4 | (setq auto-mode-alist 5 | (cons '("\\.textile\\'" . textile-mode) auto-mode-alist)) 6 | 7 | 8 | (provide 'init-textile) 9 | -------------------------------------------------------------------------------- /init-dired.el: -------------------------------------------------------------------------------- 1 | (require-package 'dired+) 2 | 3 | (setq diredp-hide-details-initially-flag nil) 4 | (setq global-dired-hide-details-mode -1) 5 | 6 | (after-load 'dired 7 | (require 'dired+) 8 | (setq dired-recursive-deletes 'top) 9 | (define-key dired-mode-map [mouse-2] 'dired-find-file)) 10 | 11 | (provide 'init-dired) 12 | -------------------------------------------------------------------------------- /init-hippie-expand.el: -------------------------------------------------------------------------------- 1 | (global-set-key (kbd "M-/") 'hippie-expand) 2 | 3 | (setq hippie-expand-try-functions-list 4 | '(try-complete-file-name-partially 5 | try-complete-file-name 6 | try-expand-dabbrev 7 | try-expand-dabbrev-all-buffers 8 | try-expand-dabbrev-from-kill)) 9 | 10 | (provide 'init-hippie-expand) -------------------------------------------------------------------------------- /init-flycheck.el: -------------------------------------------------------------------------------- 1 | (when (eval-when-compile (>= emacs-major-version 24)) 2 | (require-package 'flycheck) 3 | (add-hook 'after-init-hook 'global-flycheck-mode)) 4 | 5 | ;; Override default flycheck triggers 6 | (setq flycheck-check-syntax-automatically '(save idle-change mode-enabled) 7 | flycheck-idle-change-delay 0.8) 8 | (provide 'init-flycheck) 9 | -------------------------------------------------------------------------------- /init-darcs.el: -------------------------------------------------------------------------------- 1 | (require-package 'darcsum) 2 | (require-package 'vc-darcs) 3 | 4 | 5 | ;; TODO: include this in the vc-darcs ELPA package 6 | (add-to-list 'vc-handled-backends 'DARCS) 7 | (autoload 'vc-darcs-find-file-hook "vc-darcs") 8 | (add-hook 'find-file-hooks 'vc-darcs-find-file-hook) 9 | 10 | (setq darcsum-whatsnew-switches "-l") 11 | 12 | (provide 'init-darcs) 13 | -------------------------------------------------------------------------------- /init-exec-path.el: -------------------------------------------------------------------------------- 1 | (require-package 'exec-path-from-shell) 2 | 3 | (after-load 'exec-path-from-shell 4 | (dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO" "LANG" "LC_CTYPE")) 5 | (add-to-list 'exec-path-from-shell-variables var))) 6 | 7 | 8 | (when (memq window-system '(mac ns)) 9 | (exec-path-from-shell-initialize)) 10 | 11 | (provide 'init-exec-path) 12 | -------------------------------------------------------------------------------- /init-mmm.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Multiple major modes 3 | ;;---------------------------------------------------------------------------- 4 | (require-package 'mmm-mode) 5 | (require 'mmm-auto) 6 | (setq mmm-global-mode 'buffers-with-submode-classes) 7 | (setq mmm-submode-decoration-level 2) 8 | 9 | 10 | (provide 'init-mmm) 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /url/cache 2 | /.emacs.desktop 3 | /auto-save-list 4 | /.session 5 | /custom.el 6 | *.elc 7 | CVS 8 | .svn 9 | *~ 10 | .cvsignore 11 | .*.lock 12 | /tramp 13 | /TODO 14 | /anything-c-adaptive-history 15 | /.org-id-locations 16 | cookies 17 | /newsticker 18 | /ac-comphist.dat 19 | \#* 20 | /elpa 21 | site-lisp/package/ 22 | /swank 23 | /.mc-lists.el 24 | /var 25 | /.sqli_history 26 | /frame-restore-parameters 27 | -------------------------------------------------------------------------------- /init-rails.el: -------------------------------------------------------------------------------- 1 | (require-package 'rinari) 2 | (after-load 'rinari 3 | (diminish 'rinari-minor-mode "Rin")) 4 | (global-rinari-mode) 5 | 6 | (require-package 'haml-mode) 7 | 8 | (defun update-rails-ctags () 9 | (interactive) 10 | (let ((default-directory (or (rinari-root) default-directory))) 11 | (shell-command (concat "ctags -a -e -f " rinari-tags-file-name " --tag-relative -R app lib vendor test")))) 12 | 13 | 14 | (provide 'init-rails) 15 | -------------------------------------------------------------------------------- /init-uniquify.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Nicer naming of buffers for files with identical names 3 | ;;---------------------------------------------------------------------------- 4 | (require 'uniquify) 5 | 6 | (setq uniquify-buffer-name-style 'reverse) 7 | (setq uniquify-separator " • ") 8 | (setq uniquify-after-kill-buffer-p t) 9 | (setq uniquify-ignore-buffers-re "^\\*") 10 | 11 | 12 | (provide 'init-uniquify) -------------------------------------------------------------------------------- /init-osx-keys.el: -------------------------------------------------------------------------------- 1 | (when *is-a-mac* 2 | (setq mac-command-modifier 'meta) 3 | (setq mac-option-modifier 'none) 4 | (setq default-input-method "MacOSX") 5 | ;; Make mouse wheel / trackpad scrolling less jerky 6 | (setq mouse-wheel-scroll-amount '(0.001)) 7 | (when *is-cocoa-emacs* 8 | ;; Woohoo!! 9 | (global-set-key (kbd "M-`") 'ns-next-frame) 10 | (global-set-key (kbd "M-h") 'ns-do-hide-emacs) 11 | (after-load 'nxml-mode 12 | (define-key nxml-mode-map (kbd "M-h") nil)) 13 | (global-set-key (kbd "M-ˍ") 'ns-do-hide-others) ;; what describe-key reports for cmd-option-h 14 | )) 15 | 16 | 17 | (provide 'init-osx-keys) 18 | -------------------------------------------------------------------------------- /init-misc.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Misc config - yet to be placed in separate files 3 | ;;---------------------------------------------------------------------------- 4 | (add-auto-mode 'tcl-mode "Portfile\\'") 5 | (fset 'yes-or-no-p 'y-or-n-p) 6 | 7 | (dolist (hook (if (fboundp 'prog-mode) 8 | '(prog-mode-hook ruby-mode-hook) 9 | '(find-file-hooks))) 10 | (add-hook hook 'goto-address-prog-mode)) 11 | (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p) 12 | (setq goto-address-mail-face 'link) 13 | 14 | (setq-default regex-tool-backend 'perl) 15 | 16 | 17 | (provide 'init-misc) 18 | -------------------------------------------------------------------------------- /init-sql.el: -------------------------------------------------------------------------------- 1 | (require-package 'sql-indent) 2 | (after-load 'sql 3 | (require 'sql-indent)) 4 | 5 | (after-load 'sql 6 | (when (package-installed-p 'dash-at-point) 7 | (defun sanityinc/maybe-set-dash-db-docset () 8 | (when (eq sql-product 'postgres) 9 | (setq dash-at-point-docset "psql"))) 10 | 11 | (add-hook 'sql-mode-hook 'sanityinc/maybe-set-dash-db-docset) 12 | (add-hook 'sql-interactive-mode-hook 'sanityinc/maybe-set-dash-db-docset) 13 | (defadvice sql-set-product (after set-dash-docset activate) 14 | (sanityinc/maybe-set-dash-db-docset)))) 15 | 16 | (setq-default sql-input-ring-file-name 17 | (expand-file-name ".sqli_history" user-emacs-directory)) 18 | 19 | (provide 'init-sql) 20 | -------------------------------------------------------------------------------- /init-frame-hooks.el: -------------------------------------------------------------------------------- 1 | (defvar after-make-console-frame-hooks '() 2 | "Hooks to run after creating a new TTY frame") 3 | (defvar after-make-window-system-frame-hooks '() 4 | "Hooks to run after creating a new window-system frame") 5 | 6 | (defun run-after-make-frame-hooks (frame) 7 | "Run configured hooks in response to the newly-created FRAME. 8 | Selectively runs either `after-make-console-frame-hooks' or 9 | `after-make-window-system-frame-hooks'" 10 | (with-selected-frame frame 11 | (run-hooks (if window-system 12 | 'after-make-window-system-frame-hooks 13 | 'after-make-console-frame-hooks)))) 14 | 15 | (add-hook 'after-make-frame-functions 'run-after-make-frame-hooks) 16 | 17 | 18 | (provide 'init-frame-hooks) 19 | -------------------------------------------------------------------------------- /init-xterm.el: -------------------------------------------------------------------------------- 1 | (require 'init-frame-hooks) 2 | 3 | (defun fix-up-xterm-control-arrows () 4 | (let ((map (if (boundp 'input-decode-map) 5 | input-decode-map 6 | function-key-map))) 7 | (define-key map "\e[1;5A" [C-up]) 8 | (define-key map "\e[1;5B" [C-down]) 9 | (define-key map "\e[1;5C" [C-right]) 10 | (define-key map "\e[1;5D" [C-left]) 11 | (define-key map "\e[5A" [C-up]) 12 | (define-key map "\e[5B" [C-down]) 13 | (define-key map "\e[5C" [C-right]) 14 | (define-key map "\e[5D" [C-left]))) 15 | 16 | (add-hook 'after-make-console-frame-hooks 17 | (lambda () 18 | (when (< emacs-major-version 23) 19 | (fix-up-xterm-control-arrows)) 20 | (xterm-mouse-mode 1) ; Mouse in a terminal (Use shift to paste with middle button) 21 | (when (fboundp 'mwheel-install) 22 | (mwheel-install)))) 23 | 24 | (provide 'init-xterm) 25 | -------------------------------------------------------------------------------- /init-locales.el: -------------------------------------------------------------------------------- 1 | (defun sanityinc/utf8-locale-p (v) 2 | "Return whether locale string V relates to a UTF-8 locale." 3 | (and v (string-match "UTF-8" v))) 4 | 5 | (defun locale-is-utf8-p () 6 | "Return t iff the \"locale\" command or environment variables prefer UTF-8." 7 | (or (sanityinc/utf8-locale-p (and (executable-find "locale") (shell-command-to-string "locale"))) 8 | (sanityinc/utf8-locale-p (getenv "LC_ALL")) 9 | (sanityinc/utf8-locale-p (getenv "LC_CTYPE")) 10 | (sanityinc/utf8-locale-p (getenv "LANG")))) 11 | 12 | (when (or window-system (locale-is-utf8-p)) 13 | (setq utf-translate-cjk-mode nil) ; disable CJK coding/encoding (Chinese/Japanese/Korean characters) 14 | (set-language-environment 'utf-8) 15 | (setq locale-coding-system 'utf-8) 16 | (set-default-coding-systems 'utf-8) 17 | (set-terminal-coding-system 'utf-8) 18 | (unless (eq system-type 'windows-nt) 19 | (set-selection-coding-system 'utf-8)) 20 | (prefer-coding-system 'utf-8)) 21 | 22 | (provide 'init-locales) 23 | -------------------------------------------------------------------------------- /init-benchmarking.el: -------------------------------------------------------------------------------- 1 | (defun sanityinc/time-subtract-millis (b a) 2 | (* 1000.0 (float-time (time-subtract b a)))) 3 | 4 | 5 | (defvar sanityinc/require-times nil 6 | "A list of (FEATURE . LOAD-DURATION). 7 | LOAD-DURATION is the time taken in milliseconds to load FEATURE.") 8 | 9 | (defadvice require 10 | (around build-require-times (feature &optional filename noerror) activate) 11 | "Note in `sanityinc/require-times' the time taken to require each feature." 12 | (let* ((already-loaded (memq feature features)) 13 | (require-start-time (and (not already-loaded) (current-time)))) 14 | (prog1 15 | ad-do-it 16 | (when (and (not already-loaded) (memq feature features)) 17 | (add-to-list 'sanityinc/require-times 18 | (cons feature 19 | (sanityinc/time-subtract-millis (current-time) 20 | require-start-time)) 21 | t))))) 22 | 23 | 24 | 25 | (provide 'init-benchmarking) 26 | -------------------------------------------------------------------------------- /init-growl.el: -------------------------------------------------------------------------------- 1 | (require-package 'todochiku) 2 | 3 | (require 'todochiku) ;; growl notifications when compilation finishes 4 | (setq todochiku-icons-directory 5 | (expand-file-name "site-lisp/todochiku-icons" user-emacs-directory)) 6 | 7 | (defcustom terminal-notifier-path 8 | "/Applications/terminal-notifier.app/Contents/MacOS/terminal-notifier" 9 | "Path to the terminal-notifier app for Mountain Lion, if installed. 10 | See https://github.com/alloy/terminal-notifier for more information.") 11 | 12 | (when (and *is-a-mac* (file-executable-p terminal-notifier-path)) 13 | (defadvice todochiku-get-arguments (around todochiku-terminal-notifier activate) 14 | (setq ad-return-value 15 | (list "-title" title "-message" message "-activate" "org.gnu.Emacs"))) 16 | (setq todochiku-command terminal-notifier-path)) 17 | 18 | (defadvice todochiku-message (around check-for-helper activate) 19 | "Suppress message attempts when the `todochiku-command' program is missing." 20 | (when (executable-find todochiku-command) 21 | ad-do-it)) 22 | 23 | (provide 'init-growl) 24 | -------------------------------------------------------------------------------- /init-ido.el: -------------------------------------------------------------------------------- 1 | ;; Use C-f during file selection to switch to regular find-file 2 | (ido-mode t) 3 | (ido-everywhere t) 4 | (setq ido-enable-flex-matching t) 5 | (setq ido-use-filename-at-point nil) 6 | (setq ido-auto-merge-work-directories-length 0) 7 | (setq ido-use-virtual-buffers t) 8 | 9 | (when (eval-when-compile (>= emacs-major-version 24)) 10 | (require-package 'ido-ubiquitous) 11 | (ido-ubiquitous-mode t)) 12 | 13 | (require-package 'smex) 14 | (global-set-key (kbd "M-x") 'smex) 15 | 16 | (require-package 'idomenu) 17 | 18 | ;; Allow the same buffer to be open in different frames 19 | (setq ido-default-buffer-method 'selected-window) 20 | 21 | (when (eval-when-compile (< emacs-major-version 24)) 22 | (defun sanityinc/ido-choose-from-recentf () 23 | "Use ido to select a recently opened file from the `recentf-list'" 24 | (interactive) 25 | (if (and ido-use-virtual-buffers (fboundp 'ido-toggle-virtual-buffers)) 26 | (ido-switch-buffer) 27 | (find-file (ido-completing-read "Open file: " recentf-list nil t)))) 28 | 29 | (global-set-key [(meta f11)] 'sanityinc/ido-choose-from-recentf)) 30 | 31 | 32 | 33 | (provide 'init-ido) 34 | -------------------------------------------------------------------------------- /init-flyspell.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Add spell-checking in comments for all programming language modes 3 | ;;---------------------------------------------------------------------------- 4 | (if (fboundp 'prog-mode) 5 | (add-hook 'prog-mode-hook 'flyspell-prog-mode) 6 | (dolist (hook '(lisp-mode-hook 7 | emacs-lisp-mode-hook 8 | scheme-mode-hook 9 | clojure-mode-hook 10 | ruby-mode-hook 11 | yaml-mode 12 | python-mode-hook 13 | shell-mode-hook 14 | php-mode-hook 15 | css-mode-hook 16 | haskell-mode-hook 17 | caml-mode-hook 18 | nxml-mode-hook 19 | crontab-mode-hook 20 | perl-mode-hook 21 | tcl-mode-hook 22 | javascript-mode-hook)) 23 | (add-hook hook 'flyspell-prog-mode))) 24 | 25 | (after-load 'flyspell 26 | (add-to-list 'flyspell-prog-text-faces 'nxml-text-face)) 27 | 28 | 29 | (provide 'init-flyspell) 30 | -------------------------------------------------------------------------------- /init-haskell.el: -------------------------------------------------------------------------------- 1 | (require-package 'haskell-mode) 2 | 3 | (dolist (hook '(haskell-mode-hook inferior-haskell-mode-hook)) 4 | (add-hook hook 'turn-on-haskell-doc-mode)) 5 | 6 | (add-auto-mode 'haskell-mode "\\.ghci\\'") 7 | 8 | (add-hook 'haskell-mode-hook 'turn-on-haskell-indent) 9 | (add-hook 'haskell-mode-hook (lambda () (subword-mode +1))) 10 | 11 | (after-load 'haskell-mode 12 | (define-key haskell-mode-map (kbd "C-c h") 'hoogle) 13 | (define-key haskell-mode-map (kbd "C-o") 'open-line)) 14 | 15 | (when (eval-when-compile (>= emacs-major-version 24)) 16 | (require-package 'ghci-completion) 17 | (add-hook 'inferior-haskell-mode-hook 'turn-on-ghci-completion)) 18 | 19 | (eval-after-load 'page-break-lines 20 | '(push 'haskell-mode page-break-lines-modes)) 21 | 22 | ;; Make compilation-mode understand "at blah.hs:11:34-50" lines output by GHC 23 | (after-load 'compile 24 | (let ((alias 'ghc-at-regexp)) 25 | (add-to-list 26 | 'compilation-error-regexp-alist-alist 27 | (list alias " at \\(.*\\.\\(?:l?[gh]hs\\|hi\\)\\):\\([0-9]+\\):\\([0-9]+\\)-[0-9]+$" 1 2 3 0 1)) 28 | (add-to-list 29 | 'compilation-error-regexp-alist alias))) 30 | 31 | (provide 'init-haskell) 32 | -------------------------------------------------------------------------------- /init-nxml.el: -------------------------------------------------------------------------------- 1 | (add-auto-mode 2 | 'nxml-mode 3 | (concat "\\." 4 | (regexp-opt 5 | '("xml" "xsd" "sch" "rng" "xslt" "svg" "rss" 6 | "gpx" "tcx")) 7 | "\\'")) 8 | (setq magic-mode-alist (cons '("<\\?xml " . nxml-mode) magic-mode-alist)) 9 | (fset 'xml-mode 'nxml-mode) 10 | (add-hook 'nxml-mode-hook (lambda () 11 | (set (make-local-variable 'ido-use-filename-at-point) nil))) 12 | (setq nxml-slash-auto-complete-flag t) 13 | 14 | 15 | ;; See: http://sinewalker.wordpress.com/2008/06/26/pretty-printing-xml-with-emacs-nxml-mode/ 16 | (defun pp-xml-region (begin end) 17 | "Pretty format XML markup in region. The function inserts 18 | linebreaks to separate tags that have nothing but whitespace 19 | between them. It then indents the markup by using nxml's 20 | indentation rules." 21 | (interactive "r") 22 | (save-excursion 23 | (nxml-mode) 24 | (goto-char begin) 25 | (while (search-forward-regexp "\>[ \\t]*\<" nil t) 26 | (backward-char) (insert "\n")) 27 | (indent-region begin end))) 28 | 29 | ;;---------------------------------------------------------------------------- 30 | ;; Integration with tidy for html + xml 31 | ;;---------------------------------------------------------------------------- 32 | (require-package 'tidy) 33 | (add-hook 'nxml-mode-hook (lambda () (tidy-build-menu nxml-mode-map))) 34 | (add-hook 'html-mode-hook (lambda () (tidy-build-menu html-mode-map))) 35 | 36 | 37 | (add-auto-mode 'html-mode "\\.(jsp|tmpl)\\'") 38 | 39 | 40 | (provide 'init-nxml) 41 | -------------------------------------------------------------------------------- /init-proxies.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Pick up http_proxy & https_proxy from Mac system config using proxy-config 3 | ;; tool available from 4 | ;; http://www.cs.usyd.edu.au/~massad/project-proxy-config.html 5 | ;;---------------------------------------------------------------------------- 6 | (when (and *is-a-mac* (executable-find "proxy-config")) 7 | (defun mac-configured-proxy (proto) 8 | (string-rtrim (shell-command-to-string 9 | (concat "proxy-config " (cdr (assoc-string proto '(("http" . "-h") ("https" . "-s")))))))) 10 | 11 | (defun extract-host-and-port (url-string) 12 | (if (string-match "^[a-z]+://\\([^/]+\\)" url-string) 13 | (match-string 1 url-string) 14 | url-string)) 15 | 16 | (defun assq-delete-all-with-test (k l &optional test) 17 | (let ((test-func (or test #'eq))) 18 | (loop for entry in l 19 | unless (funcall test-func k (car entry)) 20 | collect entry))) 21 | 22 | (defun mac-set-proxy-vars () 23 | (interactive) 24 | (require 'url) 25 | (loop for proto in '("http" "https") 26 | for proxy = (mac-configured-proxy proto) 27 | do 28 | (setenv (concat proto "_proxy" proxy)) 29 | (setq url-proxy-services 30 | (append (assq-delete-all-with-test proto url-proxy-services #'equal) 31 | (if (not (equal "" proxy)) (list (cons proto (extract-host-and-port proxy))))))) 32 | (message "proxy variables updated"))) 33 | 34 | 35 | (provide 'init-proxies) 36 | -------------------------------------------------------------------------------- /init-ibuffer.el: -------------------------------------------------------------------------------- 1 | (require-package 'ibuffer-vc) 2 | 3 | (defun ibuffer-set-up-preferred-filters () 4 | (ibuffer-vc-set-filter-groups-by-vc-root) 5 | (unless (eq ibuffer-sorting-mode 'filename/process) 6 | (ibuffer-do-sort-by-filename/process))) 7 | 8 | (add-hook 'ibuffer-hook 'ibuffer-set-up-preferred-filters) 9 | 10 | 11 | 12 | (after-load 'ibuffer 13 | ;; Use human readable Size column instead of original one 14 | (define-ibuffer-column size-h 15 | (:name "Size" :inline t) 16 | (cond 17 | ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0))) 18 | ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0))) 19 | (t (format "%8d" (buffer-size)))))) 20 | 21 | 22 | ;; Explicitly require ibuffer-vc to get its column definitions, which 23 | ;; can't be autoloaded 24 | (after-load 'ibuffer 25 | (require 'ibuffer-vc)) 26 | 27 | ;; Modify the default ibuffer-formats (toggle with `) 28 | (setq ibuffer-formats 29 | '((mark modified read-only vc-status-mini " " 30 | (name 18 18 :left :elide) 31 | " " 32 | (size-h 9 -1 :right) 33 | " " 34 | (mode 16 16 :left :elide) 35 | " " 36 | filename-and-process) 37 | (mark modified read-only vc-status-mini " " 38 | (name 18 18 :left :elide) 39 | " " 40 | (size-h 9 -1 :right) 41 | " " 42 | (mode 16 16 :left :elide) 43 | " " 44 | (vc-status 16 16 :left) 45 | " " 46 | filename-and-process))) 47 | 48 | (setq ibuffer-filter-group-name-face 'font-lock-doc-face) 49 | 50 | (global-set-key (kbd "C-x C-b") 'ibuffer) 51 | 52 | (provide 'init-ibuffer) 53 | -------------------------------------------------------------------------------- /init-slime.el: -------------------------------------------------------------------------------- 1 | (require-package 'slime) 2 | ;; package.el compiles the contrib subdir, but the compilation order 3 | ;; causes problems, so we remove the .elc files there. See 4 | ;; http://lists.common-lisp.net/pipermail/slime-devel/2012-February/018470.html 5 | (mapc #'delete-file 6 | (file-expand-wildcards (concat user-emacs-directory "elpa/slime-2*/contrib/*.elc"))) 7 | 8 | (require-package 'ac-slime) 9 | (require-package 'hippie-expand-slime) 10 | 11 | 12 | ;;; Lisp buffers 13 | 14 | (defun sanityinc/slime-setup () 15 | "Mode setup function for slime lisp buffers." 16 | (set-up-slime-hippie-expand) 17 | (set-up-slime-ac t)) 18 | 19 | (after-load 'slime 20 | (setq slime-protocol-version 'ignore) 21 | (setq slime-net-coding-system 'utf-8-unix) 22 | (slime-setup '(slime-repl slime-fuzzy)) 23 | (setq slime-complete-symbol*-fancy t) 24 | (setq slime-complete-symbol-function 'slime-fuzzy-complete-symbol) 25 | (add-hook 'slime-mode-hook 'sanityinc/slime-setup)) 26 | 27 | 28 | ;;; REPL 29 | 30 | (defun sanityinc/slime-repl-setup () 31 | "Mode setup function for slime REPL." 32 | (sanityinc/lisp-setup) 33 | (set-up-slime-hippie-expand) 34 | (set-up-slime-ac t) 35 | (setq show-trailing-whitespace nil)) 36 | 37 | (after-load 'slime-repl 38 | ;; Stop SLIME's REPL from grabbing DEL, which is annoying when backspacing over a '(' 39 | (define-key slime-repl-mode-map (read-kbd-macro paredit-backward-delete-key) nil) 40 | 41 | ;; Bind TAB to `indent-for-tab-command', as in regular Slime buffers. 42 | (define-key slime-repl-mode-map (kbd "TAB") 'indent-for-tab-command) 43 | 44 | (add-hook 'slime-repl-mode-hook 'sanityinc/slime-repl-setup)) 45 | 46 | (after-load 'auto-complete 47 | (add-to-list 'ac-modes 'slime-repl-mode)) 48 | 49 | 50 | (provide 'init-slime) 51 | -------------------------------------------------------------------------------- /init-css.el: -------------------------------------------------------------------------------- 1 | ;;; Colourise CSS colour literals 2 | (when (eval-when-compile (>= emacs-major-version 24)) 3 | ;; rainbow-mode needs color.el, bundled with Emacs >= 24. 4 | (require-package 'rainbow-mode) 5 | (dolist (hook '(css-mode-hook html-mode-hook sass-mode-hook)) 6 | (add-hook hook 'rainbow-mode))) 7 | 8 | 9 | ;;; Embedding in html 10 | (require-package 'mmm-mode) 11 | (after-load 'mmm-vars 12 | (mmm-add-group 13 | 'html-css 14 | '((css-cdata 15 | :submode css-mode 16 | :face mmm-code-submode-face 17 | :front "]*>[ \t\n]*\\(//\\)?[ \t\n]*" 19 | :insert ((?j js-tag nil @ "" 26 | :insert ((?j js-tag nil @ "" @))) 28 | (css-inline 29 | :submode css-mode 30 | :face mmm-code-submode-face 31 | :front "style=\"" 32 | :back "\""))) 33 | (dolist (mode (list 'html-mode 'nxml-mode)) 34 | (mmm-add-mode-ext-class mode "\\.r?html\\(\\.erb\\)?\\'" 'html-css))) 35 | 36 | 37 | 38 | 39 | ;;; SASS and SCSS 40 | (require-package 'sass-mode) 41 | (require-package 'scss-mode) 42 | (setq-default scss-compile-at-save nil) 43 | 44 | 45 | 46 | ;;; LESS 47 | (require-package 'less-css-mode) 48 | (require-package 'skewer-less) 49 | 50 | 51 | 52 | ;;; Auto-complete CSS keywords 53 | (after-load 'auto-complete 54 | (dolist (hook '(css-mode-hook sass-mode-hook scss-mode-hook)) 55 | (add-hook hook 'ac-css-mode-setup))) 56 | 57 | 58 | ;;; Use eldoc for syntax hints 59 | (require-package 'css-eldoc) 60 | (autoload 'turn-on-css-eldoc "css-eldoc") 61 | (add-hook 'css-mode-hook 'turn-on-css-eldoc) 62 | 63 | 64 | (provide 'init-css) 65 | -------------------------------------------------------------------------------- /init-common-lisp.el: -------------------------------------------------------------------------------- 1 | ;; See http://bc.tech.coop/blog/070927.html 2 | (add-auto-mode 'lisp-mode "\\.cl\\'") 3 | (add-hook 'lisp-mode-hook (lambda () 4 | (unless (featurep 'slime) 5 | (require 'slime) 6 | (normal-mode)))) 7 | 8 | (after-load 'slime 9 | (when (executable-find "sbcl") 10 | (add-to-list 'slime-lisp-implementations 11 | '(sbcl ("sbcl") :coding-system utf-8-unix))) 12 | (when (executable-find "lisp") 13 | (add-to-list 'slime-lisp-implementations 14 | '(cmucl ("lisp") :coding-system iso-latin-1-unix)))) 15 | 16 | ;; From http://bc.tech.coop/blog/070515.html 17 | (defun lispdoc () 18 | "Searches lispdoc.com for SYMBOL, which is by default the symbol currently under the curser" 19 | (interactive) 20 | (let* ((word-at-point (word-at-point)) 21 | (symbol-at-point (symbol-at-point)) 22 | (default (symbol-name symbol-at-point)) 23 | (inp (read-from-minibuffer 24 | (if (or word-at-point symbol-at-point) 25 | (concat "Symbol (default " default "): ") 26 | "Symbol (no default): ")))) 27 | (if (and (string= inp "") (not word-at-point) (not 28 | symbol-at-point)) 29 | (message "you didn't enter a symbol!") 30 | (let ((search-type (read-from-minibuffer 31 | "full-text (f) or basic (b) search (default b)? "))) 32 | (browse-url (concat "http://lispdoc.com?q=" 33 | (if (string= inp "") 34 | default 35 | inp) 36 | "&search=" 37 | (if (string-equal search-type "f") 38 | "full+text+search" 39 | "basic+search"))))))) 40 | 41 | (define-key lisp-mode-map (kbd "C-c l") 'lispdoc) 42 | 43 | 44 | (provide 'init-common-lisp) 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A reasonable Emacs config 2 | 3 | This is my emacs configuration tree, continually used and tweaked 4 | since 2000, and it may be a good starting point for other Emacs 5 | users, especially those who are web developers. These days it's 6 | somewhat geared towards OS X, but it is known to also work on Linux 7 | and Windows. 8 | 9 | Emacs itself comes with support for many programming languages. This 10 | config adds improved defaults and extended support for the following: 11 | 12 | * Ruby / Ruby on Rails 13 | * CSS / LESS / SASS / SCSS 14 | * HAML / Markdown / Textile / ERB 15 | * Clojure (via nrepl) 16 | * Javascript / Coffeescript 17 | * Python 18 | * PHP 19 | * Haskell 20 | * Erlang 21 | * Common Lisp (with Slime) 22 | 23 | In particular, there's a nice config for *tab autocompletion*, and 24 | flycheck is used to immediately highlight syntax errors in Ruby, HAML, 25 | Python, Javascript, PHP and a number of other languages. 26 | 27 | ## Requirements 28 | 29 | * Emacs 23 or greater (note that Emacs 24 is required for some 30 | functionality, and will likely become the minimum required version 31 | some time soon.) 32 | 33 | ## Installation 34 | 35 | To install, clone this repo to `~/.emacs.d`, i.e. ensure that the 36 | `init.el` contained in this repo ends up at `~/.emacs.d/init.el`: 37 | 38 | ``` 39 | git clone https://github.com/purcell/emacs.d.git ~/.emacs.d 40 | ``` 41 | 42 | Upon starting up Emacs for the first time, further third-party 43 | packages will be automatically downloaded and installed. 44 | 45 | ## Similar configs 46 | 47 | You might also want to check out `emacs-starter-kit` and `emacs-prelude`. 48 | 49 | ## Support / issues 50 | 51 | If you hit any problems, please [file an issue on the github project](https://github.com/purcell/emacs.d) 52 | 53 | -Steve Purcell 54 | 55 |
56 | 57 | [![](http://api.coderwall.com/purcell/endorsecount.png)](http://coderwall.com/purcell) 58 | 59 | [![](http://www.linkedin.com/img/webpromo/btn_liprofile_blue_80x15.png)](http://uk.linkedin.com/in/stevepurcell) 60 | -------------------------------------------------------------------------------- /init-site-lisp.el: -------------------------------------------------------------------------------- 1 | ;;; Set load path 2 | 3 | (eval-when-compile (require 'cl)) 4 | (defun sanityinc/add-subdirs-to-load-path (parent-dir) 5 | "Adds every non-hidden subdir of PARENT-DIR to `load-path'." 6 | (let* ((default-directory parent-dir)) 7 | (progn 8 | (setq load-path 9 | (append 10 | (loop for dir in (directory-files parent-dir) 11 | unless (string-match "^\\." dir) 12 | collecting (expand-file-name dir)) 13 | load-path))))) 14 | 15 | (sanityinc/add-subdirs-to-load-path 16 | (expand-file-name "site-lisp/" user-emacs-directory)) 17 | 18 | ;;; Utilities for grabbing upstream libs 19 | 20 | (defun site-lisp-dir-for (name) 21 | (expand-file-name (format "site-lisp/%s" name) user-emacs-directory)) 22 | 23 | (defun site-lisp-library-el-path (name) 24 | (expand-file-name (format "%s.el" name) (site-lisp-dir-for name))) 25 | 26 | (defun download-site-lisp-module (name url) 27 | (let ((dir (site-lisp-dir-for name))) 28 | (message "Downloading %s from %s" name url) 29 | (unless (file-directory-p dir) 30 | (make-directory dir) 31 | (add-to-list 'load-path dir)) 32 | (let ((el-file (site-lisp-library-el-path name))) 33 | (url-copy-file url el-file t nil) 34 | el-file))) 35 | 36 | (defun ensure-lib-from-url (name url) 37 | (unless (site-lisp-library-loadable-p name) 38 | (byte-compile-file (download-site-lisp-module name url)))) 39 | 40 | (defun site-lisp-library-loadable-p (name) 41 | "Return whether or not the library `name' can be loaded from a 42 | source file under ~/.emacs.d/site-lisp/name/" 43 | (let ((f (locate-library (symbol-name name)))) 44 | (and f (string-prefix-p (file-name-as-directory (site-lisp-dir-for name)) f)))) 45 | 46 | 47 | 48 | ;; Download these upstream libs 49 | 50 | (unless (> emacs-major-version 23) 51 | (ensure-lib-from-url 52 | 'package 53 | "http://repo.or.cz/w/emacs.git/blob_plain/1a0a666f941c99882093d7bd08ced15033bc3f0c:/lisp/emacs-lisp/package.el")) 54 | 55 | 56 | (provide 'init-site-lisp) 57 | -------------------------------------------------------------------------------- /init-fonts.el: -------------------------------------------------------------------------------- 1 | ;;; Character sets 2 | 3 | (defcustom sanityinc/force-default-font-for-symbols nil 4 | "When non-nil, force Emacs to use your default font for symbols." 5 | :type 'boolean) 6 | 7 | (defun sanityinc/maybe-use-default-font-for-symbols () 8 | "Force Emacs to render symbols using the default font, if so configured." 9 | (when sanityinc/force-default-font-for-symbols 10 | (set-fontset-font "fontset-default" 'symbol (face-attribute 'default :family)))) 11 | 12 | (add-hook 'after-init-hook 'sanityinc/maybe-use-default-font-for-symbols) 13 | 14 | 15 | ;;; Changing font sizes 16 | 17 | (require 'cl) 18 | 19 | (defun sanityinc/font-name-replace-size (font-name new-size) 20 | (let ((parts (split-string font-name "-"))) 21 | (setcar (nthcdr 7 parts) (format "%d" new-size)) 22 | (mapconcat 'identity parts "-"))) 23 | 24 | (defun sanityinc/increment-default-font-height (delta) 25 | "Adjust the default font height by DELTA on every frame. 26 | Emacs will keep the pixel size of the frame approximately the 27 | same. DELTA should be a multiple of 10, to match the units used 28 | by the :height face attribute." 29 | (let* ((new-height (+ (face-attribute 'default :height) delta)) 30 | (new-point-height (/ new-height 10))) 31 | (dolist (f (frame-list)) 32 | (with-selected-frame f 33 | ;; Latest 'set-frame-font supports a "frames" arg, but 34 | ;; we cater to Emacs 23 by looping instead. 35 | (set-frame-font (sanityinc/font-name-replace-size 36 | (face-font 'default) 37 | new-point-height) 38 | t))) 39 | (set-face-attribute 'default nil :height new-height) 40 | (message "default font size is now %d" new-point-height))) 41 | 42 | (defun sanityinc/increase-default-font-height () 43 | (interactive) 44 | (sanityinc/increment-default-font-height 10)) 45 | 46 | (defun sanityinc/decrease-default-font-height () 47 | (interactive) 48 | (sanityinc/increment-default-font-height -10)) 49 | 50 | (global-set-key (kbd "C-M-=") 'sanityinc/increase-default-font-height) 51 | (global-set-key (kbd "C-M--") 'sanityinc/decrease-default-font-height) 52 | 53 | 54 | 55 | (provide 'init-fonts) 56 | -------------------------------------------------------------------------------- /init-paredit.el: -------------------------------------------------------------------------------- 1 | (require-package 'paredit) 2 | (autoload 'enable-paredit-mode "paredit") 3 | 4 | (defun maybe-map-paredit-newline () 5 | (unless (or (memq major-mode '(inferior-emacs-lisp-mode nrepl-mode)) 6 | (minibufferp)) 7 | (local-set-key (kbd "RET") 'paredit-newline))) 8 | 9 | (add-hook 'paredit-mode-hook 'maybe-map-paredit-newline) 10 | 11 | (after-load 'paredit 12 | (diminish 'paredit-mode " Par") 13 | (dolist (binding (list (kbd "C-") (kbd "C-") 14 | (kbd "C-M-") (kbd "C-M-"))) 15 | (define-key paredit-mode-map binding nil)) 16 | 17 | ;; Disable kill-sentence, which is easily confused with the kill-sexp 18 | ;; binding, but doesn't preserve sexp structure 19 | (define-key paredit-mode-map [remap kill-sentence] nil) 20 | (define-key paredit-mode-map [remap backward-kill-sentence] nil)) 21 | 22 | 23 | ;; Compatibility with other modes 24 | 25 | (suspend-mode-during-cua-rect-selection 'paredit-mode) 26 | 27 | 28 | ;; Use paredit in the minibuffer 29 | ;; TODO: break out into separate package 30 | ;; http://emacsredux.com/blog/2013/04/18/evaluate-emacs-lisp-in-the-minibuffer/ 31 | (add-hook 'minibuffer-setup-hook 'conditionally-enable-paredit-mode) 32 | 33 | (defvar paredit-minibuffer-commands '(eval-expression 34 | pp-eval-expression 35 | eval-expression-with-eldoc 36 | ibuffer-do-eval 37 | ibuffer-do-view-and-eval) 38 | "Interactive commands for which paredit should be enabled in the minibuffer.") 39 | 40 | (defun conditionally-enable-paredit-mode () 41 | "Enable paredit during lisp-related minibuffer commands." 42 | (if (memq this-command paredit-minibuffer-commands) 43 | (enable-paredit-mode))) 44 | 45 | ;; ---------------------------------------------------------------------------- 46 | ;; Enable some handy paredit functions in all prog modes 47 | ;; ---------------------------------------------------------------------------- 48 | 49 | (require-package 'paredit-everywhere) 50 | (add-hook 'prog-mode-hook 'paredit-everywhere-mode) 51 | (add-hook 'css-mode-hook 'paredit-everywhere-mode) 52 | 53 | (provide 'init-paredit) 54 | -------------------------------------------------------------------------------- /init-compat.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Provide a version of Emacs 24's 'string-prefix-p in older emacsen 3 | ;;---------------------------------------------------------------------------- 4 | (when (eval-when-compile (< emacs-major-version 24)) 5 | (defun string-prefix-p (str1 str2 &optional ignore-case) 6 | "Return non-nil if STR1 is a prefix of STR2. 7 | If IGNORE-CASE is non-nil, the comparison is done without paying attention 8 | to case differences." 9 | (eq t (compare-strings str1 nil nil 10 | str2 0 (length str1) ignore-case)))) 11 | 12 | 13 | ;;---------------------------------------------------------------------------- 14 | ;; Allow recent packages to safely pass an arg to 'called-interactively-p 15 | ;; in older Emacsen, including 23.1. 16 | ;;---------------------------------------------------------------------------- 17 | (let ((fn (symbol-function 'called-interactively-p))) 18 | (when (and (subrp fn) (zerop (cdr-safe (subr-arity fn)))) 19 | (message "Warning: overriding called-interactively-p to support an argument.") 20 | (fset 'sanityinc/called-interactively-p fn) 21 | (defun called-interactively-p (&optional kind) 22 | "Overridden; see `sanityinc/called-interactively-p' for the wrapped function." 23 | (sanityinc/called-interactively-p)))) 24 | 25 | (when (eval-when-compile (< emacs-major-version 24)) 26 | ;; Help package.el work in older Emacsen, where there's no TRASH arg 27 | ;; for 'delete-directory 28 | (message "Warning: overriding delete-directory to support TRASH argument.") 29 | (fset 'sanityinc/delete-directory (symbol-function 'delete-directory)) 30 | (defun delete-directory (directory &optional recursive trash) 31 | "Overridden: see `sanityinc/delete-directory' for the wrapped function" 32 | (sanityinc/delete-directory directory recursive))) 33 | 34 | 35 | ;;---------------------------------------------------------------------------- 36 | ;; Restore removed var alias, used by ruby-electric-brace and others 37 | ;;---------------------------------------------------------------------------- 38 | (unless (boundp 'last-command-char) 39 | (defvaralias 'last-command-char 'last-command-event)) 40 | 41 | 42 | (provide 'init-compat) 43 | -------------------------------------------------------------------------------- /init-auto-complete.el: -------------------------------------------------------------------------------- 1 | (require-package 'auto-complete) 2 | (require 'auto-complete-config) 3 | (global-auto-complete-mode t) 4 | (setq ac-expand-on-auto-complete nil) 5 | (setq ac-auto-start nil) 6 | (setq ac-dwim nil) ; To get pop-ups with docs even if a word is uniquely completed 7 | 8 | ;;---------------------------------------------------------------------------- 9 | ;; Use Emacs' built-in TAB completion hooks to trigger AC (Emacs >= 23.2) 10 | ;;---------------------------------------------------------------------------- 11 | (setq tab-always-indent 'complete) ;; use 't when auto-complete is disabled 12 | (add-to-list 'completion-styles 'initials t) 13 | 14 | ;; TODO: find solution for php, c++, haskell modes where TAB always does something 15 | 16 | ;; hook AC into completion-at-point 17 | (defun sanityinc/auto-complete-at-point () 18 | (when (and (not (minibufferp)) 19 | (fboundp 'auto-complete-mode) 20 | auto-complete-mode) 21 | (auto-complete))) 22 | 23 | (defun set-auto-complete-as-completion-at-point-function () 24 | (setq completion-at-point-functions 25 | (cons 'sanityinc/auto-complete-at-point 26 | (remove 'sanityinc/auto-complete-at-point completion-at-point-functions)))) 27 | 28 | (add-hook 'auto-complete-mode-hook 'set-auto-complete-as-completion-at-point-function) 29 | 30 | 31 | (set-default 'ac-sources 32 | '(ac-source-imenu 33 | ac-source-dictionary 34 | ac-source-words-in-buffer 35 | ac-source-words-in-same-mode-buffers 36 | ac-source-words-in-all-buffer)) 37 | 38 | (dolist (mode '(magit-log-edit-mode log-edit-mode org-mode text-mode haml-mode 39 | sass-mode yaml-mode csv-mode espresso-mode haskell-mode 40 | html-mode nxml-mode sh-mode smarty-mode clojure-mode 41 | lisp-mode textile-mode markdown-mode tuareg-mode 42 | js3-mode css-mode less-css-mode sql-mode inferior-emacs-lisp-mode)) 43 | (add-to-list 'ac-modes mode)) 44 | 45 | 46 | ;; Exclude very large buffers from dabbrev 47 | (defun sanityinc/dabbrev-friend-buffer (other-buffer) 48 | (< (buffer-size other-buffer) (* 1 1024 1024))) 49 | 50 | (setq dabbrev-friend-buffer-function 'sanityinc/dabbrev-friend-buffer) 51 | 52 | 53 | (provide 'init-auto-complete) 54 | -------------------------------------------------------------------------------- /init-maxframe.el: -------------------------------------------------------------------------------- 1 | (require-package 'maxframe) 2 | 3 | (autoload 'mf-max-display-pixel-width "maxframe" "" nil) 4 | (autoload 'mf-max-display-pixel-height "maxframe" "" nil) 5 | (autoload 'maximize-frame "maxframe" "" t) 6 | (autoload 'restore-frame "maxframe" "" t) 7 | 8 | (when *is-cocoa-emacs* 9 | (after-load 'maxframe 10 | (fset 'maximize-frame 'x-maximize-frame) 11 | (fset 'restore-frame 'x-restore-frame))) 12 | 13 | (when *is-a-mac* 14 | (setq mf-display-padding-width 4 15 | mf-offset-x 0 16 | mf-offset-y 0 17 | mf-display-padding-height (if (when (boundp 'ns-auto-hide-menu-bar) 18 | ns-auto-hide-menu-bar) 19 | 23 20 | (+ 27 23)))) 21 | 22 | (defvar sanityinc/prev-frame nil "The selected frame before invoking `make-frame-command'.") 23 | (defadvice make-frame-command (before sanityinc/note-previous-frame activate) 24 | "Record the selected frame before creating a new one interactively." 25 | (setq sanityinc/prev-frame (selected-frame))) 26 | 27 | (defun sanityinc/maybe-maximize-frame (&optional frame) 28 | (with-selected-frame (or frame (selected-frame)) 29 | (when (and window-system 30 | sanityinc/prev-frame 31 | (sanityinc/maximized-p sanityinc/prev-frame)) 32 | (maximize-frame)))) 33 | 34 | (add-hook 'after-make-frame-functions 'sanityinc/maybe-maximize-frame) 35 | (add-hook 'after-init-hook 'sanityinc/maybe-maximize-frame) 36 | 37 | (defadvice maximize-frame (around skip-if-fullscreen (&optional frame) activate) 38 | (unless (sanityinc/maximized-p frame) 39 | ad-do-it)) 40 | 41 | (defadvice restore-frame (around skip-if-fullscreen (&optional frame) activate) 42 | (when (sanityinc/maximized-p frame) 43 | ad-do-it)) 44 | 45 | (defun within-p (a b delta) 46 | (<= (abs (- b a)) delta)) 47 | 48 | (defun sanityinc/maximized-p (&optional frame) 49 | (or (not (with-selected-frame (or frame (selected-frame)) window-system)) 50 | (eq 'fullboth (frame-parameter frame 'fullscreen)) 51 | (and (within-p (mf-max-display-pixel-width) 52 | (frame-pixel-width frame) 53 | (frame-char-width frame)) 54 | (within-p (mf-max-display-pixel-height) 55 | (+ mf-display-padding-height (frame-pixel-height frame)) 56 | (frame-char-height frame))))) 57 | 58 | 59 | (provide 'init-maxframe) 60 | -------------------------------------------------------------------------------- /init-clojure.el: -------------------------------------------------------------------------------- 1 | (require-package 'clojure-mode) 2 | (require-package 'clojure-test-mode) 3 | (require-package 'cljsbuild-mode) 4 | (require-package 'elein) 5 | (require-package 'nrepl) 6 | (require-package 'slamhound) 7 | (require-package 'ac-nrepl) 8 | 9 | 10 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 11 | ;; Slime with Clojure 12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 13 | 14 | (defun slime-clojure-repl-setup () 15 | "Some REPL setup additional to that in durendal." 16 | (when (string-equal (slime-lisp-implementation-name) "clojure") 17 | (when (slime-inferior-process) 18 | (message "Setting up repl for clojure") 19 | (slime-redirect-inferior-output)) 20 | 21 | (set-syntax-table clojure-mode-syntax-table) 22 | (setq lisp-indent-function 'clojure-indent-function) 23 | (let (font-lock-mode) 24 | (clojure-mode-font-lock-setup)))) 25 | 26 | (after-load 'slime-repl 27 | (add-hook 'slime-repl-mode-hook 'slime-clojure-repl-setup)) 28 | 29 | 30 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 31 | ;; nrepl with Clojure 32 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 33 | 34 | (setq nrepl-popup-stacktraces nil) 35 | 36 | (after-load 'nrepl 37 | (add-hook 'nrepl-mode-hook 'ac-nrepl-setup) 38 | (add-hook 'nrepl-interaction-mode-hook 'ac-nrepl-setup) 39 | (after-load 'auto-complete 40 | (add-to-list 'ac-modes 'nrepl-mode)) 41 | 42 | (add-hook 'nrepl-mode-hook 'set-auto-complete-as-completion-at-point-function) 43 | (add-hook 'nrepl-interaction-mode-hook 'set-auto-complete-as-completion-at-point-function) 44 | (add-hook 'nrepl-interaction-mode-hook 'nrepl-turn-on-eldoc-mode) 45 | (add-hook 'nrepl-mode-hook 'subword-mode) 46 | (add-hook 'nrepl-mode-hook 'paredit-mode) 47 | (define-key nrepl-interaction-mode-map (kbd "C-c C-d") 'ac-nrepl-popup-doc) 48 | 49 | ;; nrepl isn't based on comint 50 | (add-hook 'nrepl-mode-hook 51 | (lambda () (setq show-trailing-whitespace nil)))) 52 | 53 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 54 | ;; Misc clojure tweaks 55 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 56 | 57 | (after-load 'clojure-mode 58 | (add-hook 'clojure-mode-hook 'sanityinc/lisp-setup) 59 | (add-hook 'clojure-mode-hook 'subword-mode)) 60 | 61 | 62 | 63 | ;; Use clojure-mode for clojurescript, since clojurescript-mode 64 | ;; pulls in Slime 65 | (add-auto-mode 'clojure-mode "\\.cljs\\'") 66 | 67 | 68 | (provide 'init-clojure) 69 | -------------------------------------------------------------------------------- /init-gui-frames.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Stop C-z from minimizing windows under OS X 3 | ;;---------------------------------------------------------------------------- 4 | (defun maybe-suspend-frame () 5 | (interactive) 6 | (unless (and *is-a-mac* window-system) 7 | (suspend-frame))) 8 | 9 | (global-set-key (kbd "C-z") 'maybe-suspend-frame) 10 | 11 | 12 | ;;---------------------------------------------------------------------------- 13 | ;; Suppress GUI features 14 | ;;---------------------------------------------------------------------------- 15 | (setq use-file-dialog nil) 16 | (setq use-dialog-box nil) 17 | (setq inhibit-startup-screen t) 18 | (setq inhibit-startup-echo-area-message t) 19 | 20 | 21 | ;;---------------------------------------------------------------------------- 22 | ;; Show a marker in the left fringe for lines not in the buffer 23 | ;;---------------------------------------------------------------------------- 24 | (setq indicate-empty-lines t) 25 | 26 | 27 | ;;---------------------------------------------------------------------------- 28 | ;; Window size and features 29 | ;;---------------------------------------------------------------------------- 30 | (when (fboundp 'tool-bar-mode) 31 | (tool-bar-mode -1)) 32 | (when (fboundp 'set-scroll-bar-mode) 33 | (set-scroll-bar-mode nil)) 34 | 35 | (defun adjust-opacity (frame incr) 36 | (let* ((oldalpha (or (frame-parameter frame 'alpha) 100)) 37 | (newalpha (+ incr oldalpha))) 38 | (when (and (<= frame-alpha-lower-limit newalpha) (>= 100 newalpha)) 39 | (modify-frame-parameters frame (list (cons 'alpha newalpha)))))) 40 | 41 | (when (and *is-a-mac* (fboundp 'toggle-frame-fullscreen)) 42 | ;; Command-Option-f to toggle fullscreen mode 43 | ;; Hint: Customize `ns-use-native-fullscreen' 44 | (global-set-key (kbd "M-ƒ") 'toggle-frame-fullscreen)) 45 | 46 | (global-set-key (kbd "M-C-8") '(lambda () (interactive) (adjust-opacity nil -5))) 47 | (global-set-key (kbd "M-C-9") '(lambda () (interactive) (adjust-opacity nil 5))) 48 | (global-set-key (kbd "M-C-0") '(lambda () (interactive) (modify-frame-parameters nil `((alpha . 100))))) 49 | 50 | (add-hook 'after-make-frame-functions 51 | (lambda (frame) 52 | (with-selected-frame frame 53 | (unless window-system 54 | (set-frame-parameter nil 'menu-bar-lines 0))))) 55 | 56 | (setq frame-title-format 57 | '((:eval (if (buffer-file-name) 58 | (abbreviate-file-name (buffer-file-name)) 59 | "%b")))) 60 | 61 | (provide 'init-gui-frames) 62 | -------------------------------------------------------------------------------- /init-windows.el: -------------------------------------------------------------------------------- 1 | ;;---------------------------------------------------------------------------- 2 | ;; Navigate window layouts with "C-c " and "C-c " 3 | ;;---------------------------------------------------------------------------- 4 | (winner-mode 1) 5 | 6 | 7 | 8 | ;; Make "C-x o" prompt for a target window when there are more than 2 9 | (require-package 'switch-window) 10 | (require 'switch-window) 11 | (setq switch-window-shortcut-style 'alphabet) 12 | 13 | 14 | ;;---------------------------------------------------------------------------- 15 | ;; When splitting window, show (other-buffer) in the new window 16 | ;;---------------------------------------------------------------------------- 17 | (defun split-window-func-with-other-buffer (split-function) 18 | (lexical-let ((s-f split-function)) 19 | (lambda () 20 | (interactive) 21 | (funcall s-f) 22 | (set-window-buffer (next-window) (other-buffer))))) 23 | 24 | (global-set-key "\C-x2" (split-window-func-with-other-buffer 'split-window-vertically)) 25 | (global-set-key "\C-x3" (split-window-func-with-other-buffer 'split-window-horizontally)) 26 | 27 | 28 | ;;---------------------------------------------------------------------------- 29 | ;; Rearrange split windows 30 | ;;---------------------------------------------------------------------------- 31 | (defun split-window-horizontally-instead () 32 | (interactive) 33 | (save-excursion 34 | (delete-other-windows) 35 | (funcall (split-window-func-with-other-buffer 'split-window-horizontally)))) 36 | 37 | (defun split-window-vertically-instead () 38 | (interactive) 39 | (save-excursion 40 | (delete-other-windows) 41 | (funcall (split-window-func-with-other-buffer 'split-window-vertically)))) 42 | 43 | (global-set-key "\C-x|" 'split-window-horizontally-instead) 44 | (global-set-key "\C-x_" 'split-window-vertically-instead) 45 | 46 | 47 | ;; Borrowed from http://postmomentum.ch/blog/201304/blog-on-emacs 48 | (defun sanityinc/split-window() 49 | "Split the window to see the most recent buffer in the other window. 50 | Call a second time to restore the original window configuration." 51 | (interactive) 52 | (if (eq last-command 'sanityinc/split-window) 53 | (progn 54 | (jump-to-register :sanityinc/split-window) 55 | (setq this-command 'sanityinc/unsplit-window)) 56 | (window-configuration-to-register :sanityinc/split-window) 57 | (switch-to-buffer-other-window nil))) 58 | 59 | (global-set-key (kbd "") 'sanityinc/split-window) 60 | (global-set-key (kbd "") 61 | (lambda () 62 | (interactive) 63 | (switch-to-buffer nil))) 64 | 65 | 66 | (provide 'init-windows) 67 | -------------------------------------------------------------------------------- /init-isearch.el: -------------------------------------------------------------------------------- 1 | ;; Show number of matches while searching 2 | (require-package 'anzu) 3 | (global-anzu-mode t) 4 | (diminish 'anzu-mode) 5 | 6 | ;; Activate occur easily inside isearch 7 | (define-key isearch-mode-map (kbd "C-o") 'isearch-occur) 8 | 9 | ;; Search back/forth for the symbol at point 10 | ;; See http://www.emacswiki.org/emacs/SearchAtPoint 11 | (defun isearch-yank-symbol () 12 | "*Put symbol at current point into search string." 13 | (interactive) 14 | (let ((sym (symbol-at-point))) 15 | (if sym 16 | (progn 17 | (setq isearch-regexp t 18 | isearch-string (concat "\\_<" (regexp-quote (symbol-name sym)) "\\_>") 19 | isearch-message (mapconcat 'isearch-text-char-description isearch-string "") 20 | isearch-yank-flag t)) 21 | (ding))) 22 | (isearch-search-and-update)) 23 | 24 | (define-key isearch-mode-map "\C-\M-w" 'isearch-yank-symbol) 25 | 26 | 27 | ;; http://www.emacswiki.org/emacs/ZapToISearch 28 | (defun zap-to-isearch (rbeg rend) 29 | "Kill the region between the mark and the closest portion of 30 | the isearch match string. The behaviour is meant to be analogous 31 | to zap-to-char; let's call it zap-to-isearch. The deleted region 32 | does not include the isearch word. This is meant to be bound only 33 | in isearch mode. The point of this function is that oftentimes 34 | you want to delete some portion of text, one end of which happens 35 | to be an active isearch word. The observation to make is that if 36 | you use isearch a lot to move the cursor around (as you should, 37 | it is much more efficient than using the arrows), it happens a 38 | lot that you could just delete the active region between the mark 39 | and the point, not include the isearch word." 40 | (interactive "r") 41 | (when (not mark-active) 42 | (error "Mark is not active")) 43 | (let* ((isearch-bounds (list isearch-other-end (point))) 44 | (ismin (apply 'min isearch-bounds)) 45 | (ismax (apply 'max isearch-bounds)) 46 | ) 47 | (if (< (mark) ismin) 48 | (kill-region (mark) ismin) 49 | (if (> (mark) ismax) 50 | (kill-region ismax (mark)) 51 | (error "Internal error in isearch kill function."))) 52 | (isearch-exit) 53 | )) 54 | 55 | (define-key isearch-mode-map [(meta z)] 'zap-to-isearch) 56 | 57 | 58 | ;; http://www.emacswiki.org/emacs/ZapToISearch 59 | (defun isearch-exit-other-end (rbeg rend) 60 | "Exit isearch, but at the other end of the search string. 61 | This is useful when followed by an immediate kill." 62 | (interactive "r") 63 | (isearch-exit) 64 | (goto-char isearch-other-end)) 65 | 66 | (define-key isearch-mode-map [(control return)] 'isearch-exit-other-end) 67 | 68 | 69 | (provide 'init-isearch) 70 | -------------------------------------------------------------------------------- /init-sessions.el: -------------------------------------------------------------------------------- 1 | ;; save a list of open files in ~/.emacs.d/.emacs.desktop 2 | (setq desktop-path (list user-emacs-directory)) 3 | (desktop-save-mode 1) 4 | (defadvice desktop-read (around trace-desktop-errors activate) 5 | (let ((debug-on-error t)) 6 | ad-do-it)) 7 | 8 | (defadvice desktop-read (around time-restore activate) 9 | (let ((start-time (current-time))) 10 | (prog1 11 | ad-do-it 12 | (message "Desktop restored in %.2fms" 13 | (sanityinc/time-subtract-millis (current-time) 14 | start-time))))) 15 | 16 | (defadvice desktop-create-buffer (around time-create activate) 17 | (let ((start-time (current-time)) 18 | (filename (ad-get-arg 1))) 19 | (prog1 20 | ad-do-it 21 | (message "Desktop: %.2fms to restore %s" 22 | (sanityinc/time-subtract-millis (current-time) 23 | start-time) 24 | (when filename 25 | (abbreviate-file-name filename)))))) 26 | 27 | ;;---------------------------------------------------------------------------- 28 | ;; Restore histories and registers after saving 29 | ;;---------------------------------------------------------------------------- 30 | (require-package 'session) 31 | 32 | (setq session-save-file (expand-file-name ".session" user-emacs-directory)) 33 | (add-hook 'after-init-hook 'session-initialize) 34 | 35 | ;; save a bunch of variables to the desktop file 36 | ;; for lists specify the len of the maximal saved data also 37 | (setq desktop-globals-to-save 38 | (append '((extended-command-history . 30) 39 | (file-name-history . 100) 40 | (ido-last-directory-list . 100) 41 | (ido-work-directory-list . 100) 42 | (ido-work-file-list . 100) 43 | (grep-history . 30) 44 | (compile-history . 30) 45 | (minibuffer-history . 50) 46 | (query-replace-history . 60) 47 | (read-expression-history . 60) 48 | (regexp-history . 60) 49 | (regexp-search-ring . 20) 50 | (search-ring . 20) 51 | (comint-input-ring . 50) 52 | (shell-command-history . 50) 53 | desktop-missing-file-warning 54 | tags-file-name 55 | register-alist))) 56 | 57 | (when (eval-when-compile (and (>= emacs-major-version 24) 58 | (string< emacs-version "24.3.50") 59 | )) 60 | (unless (boundp 'desktop-restore-frames) 61 | (require-package 'frame-restore) 62 | (frame-restore))) 63 | 64 | 65 | (provide 'init-sessions) 66 | -------------------------------------------------------------------------------- /init-marmalade.el: -------------------------------------------------------------------------------- 1 | (require-package 'marmalade) 2 | 3 | ;;; Handy code for uploading new versions of my own packages to marmalade 4 | 5 | (autoload 'marmalade-upload-buffer "marmalade") 6 | 7 | (defun sanityinc/parse-git-version (s) 8 | "Return numeric version array parsed from S, or nil." 9 | (ignore-errors (version-to-list s))) 10 | 11 | (defun latest-version-from-git-tag () 12 | (let ((versions 13 | (remove-if #'null 14 | (mapcar #'sanityinc/parse-git-version 15 | (split-string (shell-command-to-string "git tag")))))) 16 | (sort versions #'version-list-<) 17 | (package-version-join (car (last versions))))) 18 | 19 | (defun update-version-header (val) 20 | (save-excursion 21 | (goto-char (point-min)) 22 | (re-search-forward "^;;;? ?Version:") 23 | (kill-line) 24 | (insert " " val))) 25 | 26 | (defun submit-tar-to-marmalade (buf) 27 | (interactive "bSubmit buffer library as tar: ") 28 | (with-current-buffer buf 29 | (let* ((tag (or (latest-version-from-git-tag) (error "Not tagged"))) 30 | (library-name (file-name-nondirectory (file-name-sans-extension buffer-file-name))) 31 | (package-dir-name (concat library-name "-" tag)) 32 | (temp-working-dir (make-temp-file "emacs-marmalade" t)) 33 | (dest (expand-file-name package-dir-name temp-working-dir)) 34 | (tar-cmd (or (executable-find "gtar") 35 | (executable-find "tar"))) 36 | (tar (concat dest ".tar"))) 37 | (message "Building package in %s" dest) 38 | (make-directory dest) 39 | (let ((command-line (format "cp *.el %s && (cd %s && perl -spi -e 's/\\{\\{VERSION\\}\\}/%s/' *.el) && (cd %s && %s cvf %s %s)" dest dest tag temp-working-dir tar-cmd tar package-dir-name))) 40 | (shell-command command-line)) 41 | (save-excursion 42 | (shell-command (format "open %s" temp-working-dir)) 43 | ;; (find-file tar) 44 | ;; (marmalade-upload-buffer (current-buffer)) 45 | ;; (delete-directory temp-working-dir t) 46 | )))) 47 | 48 | (defun submit-to-marmalade (buf) 49 | "Submit the elisp library in BUF to Marmalade." 50 | (interactive 51 | (list 52 | (let ((buffers (loop for b in (mapcar 'buffer-name (buffer-list)) 53 | when (with-current-buffer b 54 | (and buffer-file-name 55 | (eq major-mode 'emacs-lisp-mode))) 56 | collect b))) 57 | (completing-read "Submit buffer: " buffers nil t nil nil (car buffers))))) 58 | (with-current-buffer buf 59 | (let ((tag (latest-version-from-git-tag))) 60 | (unless tag 61 | (error "Not tagged")) 62 | (update-version-header tag) 63 | (marmalade-upload-buffer buf) 64 | (revert-buffer t t) 65 | (message "Submitted version %s to marmalade" tag)))) 66 | 67 | 68 | (provide 'init-marmalade) 69 | -------------------------------------------------------------------------------- /init-elpa.el: -------------------------------------------------------------------------------- 1 | ;;; Find and load the correct package.el 2 | 3 | ;; When switching between Emacs 23 and 24, we always use the bundled package.el in Emacs 24 4 | (let ((package-el-site-lisp-dir 5 | (expand-file-name "site-lisp/package" user-emacs-directory))) 6 | (when (and (file-directory-p package-el-site-lisp-dir) 7 | (> emacs-major-version 23)) 8 | (message "Removing local package.el from load-path to avoid shadowing bundled version") 9 | (setq load-path (remove package-el-site-lisp-dir load-path)))) 10 | 11 | (require 'package) 12 | 13 | 14 | 15 | ;;; Add support to package.el for pre-filtering available packages 16 | 17 | (defvar package-filter-function nil 18 | "Optional predicate function used to internally filter packages used by package.el. 19 | 20 | The function is called with the arguments PACKAGE VERSION ARCHIVE, where 21 | PACKAGE is a symbol, VERSION is a vector as produced by `version-to-list', and 22 | ARCHIVE is the string name of the package archive.") 23 | 24 | (defadvice package--add-to-archive-contents 25 | (around filter-packages (package archive) activate) 26 | "Add filtering of available packages using `package-filter-function', if non-nil." 27 | (when (or (null package-filter-function) 28 | (funcall package-filter-function 29 | (car package) 30 | (funcall (if (fboundp 'package-desc-version) 31 | 'package--ac-desc-version 32 | 'package-desc-vers) 33 | (cdr package)) 34 | archive)) 35 | ad-do-it)) 36 | 37 | 38 | 39 | ;;; Standard package repositories 40 | 41 | (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/")) 42 | 43 | ;; We include the org repository for completeness, but don't normally 44 | ;; use it. 45 | (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")) 46 | 47 | (when (< emacs-major-version 24) 48 | (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))) 49 | 50 | ;;; Also use Melpa for most packages 51 | (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/")) 52 | 53 | ;; But don't take Melpa versions of certain packages 54 | (setq package-filter-function 55 | (lambda (package version archive) 56 | (or (not (string-equal archive "melpa")) 57 | (not (memq package '()))))) 58 | 59 | 60 | 61 | ;;; On-demand installation of packages 62 | 63 | (defun require-package (package &optional min-version no-refresh) 64 | "Install given PACKAGE, optionally requiring MIN-VERSION. 65 | If NO-REFRESH is non-nil, the available package lists will not be 66 | re-downloaded in order to locate PACKAGE." 67 | (if (package-installed-p package min-version) 68 | t 69 | (if (or (assoc package package-archive-contents) no-refresh) 70 | (package-install package) 71 | (progn 72 | (package-refresh-contents) 73 | (require-package package min-version t))))) 74 | 75 | 76 | 77 | ;;; Fire up package.el 78 | 79 | (package-initialize) 80 | 81 | 82 | (provide 'init-elpa) 83 | -------------------------------------------------------------------------------- /init-themes.el: -------------------------------------------------------------------------------- 1 | (when (< emacs-major-version 24) 2 | (require-package 'color-theme)) 3 | 4 | (require-package 'color-theme-sanityinc-solarized) 5 | (require-package 'color-theme-sanityinc-tomorrow) 6 | 7 | ;;------------------------------------------------------------------------------ 8 | ;; Old-style color theming support (via color-theme.el) 9 | ;;------------------------------------------------------------------------------ 10 | (defcustom window-system-color-theme 'color-theme-sanityinc-solarized-dark 11 | "Color theme to use in window-system frames. 12 | If Emacs' native theme support is available, this setting is 13 | ignored: use `custom-enabled-themes' instead." 14 | :type 'symbol) 15 | 16 | (defcustom tty-color-theme 'color-theme-terminal 17 | "Color theme to use in TTY frames. 18 | If Emacs' native theme support is available, this setting is 19 | ignored: use `custom-enabled-themes' instead." 20 | :type 'symbol) 21 | 22 | (unless (boundp 'custom-enabled-themes) 23 | (defun color-theme-terminal () 24 | (interactive) 25 | (color-theme-sanityinc-solarized-dark)) 26 | 27 | (defun apply-best-color-theme-for-frame-type (frame) 28 | (with-selected-frame frame 29 | (funcall (if window-system 30 | window-system-color-theme 31 | tty-color-theme)))) 32 | 33 | (defun reapply-color-themes () 34 | (interactive) 35 | (mapcar 'apply-best-color-theme-for-frame-type (frame-list))) 36 | 37 | (set-variable 'color-theme-is-global nil) 38 | (add-hook 'after-make-frame-functions 'apply-best-color-theme-for-frame-type) 39 | (add-hook 'after-init-hook 'reapply-color-themes) 40 | (apply-best-color-theme-for-frame-type (selected-frame))) 41 | 42 | 43 | ;;------------------------------------------------------------------------------ 44 | ;; New-style theme support, in which per-frame theming is not possible 45 | ;;------------------------------------------------------------------------------ 46 | 47 | ;; If you don't customize it, this is the theme you get. 48 | (setq-default custom-enabled-themes '(sanityinc-solarized-light)) 49 | 50 | ;; Ensure that themes will be applied even if they have not been customized 51 | (defun reapply-themes () 52 | "Forcibly load the themes listed in `custom-enabled-themes'." 53 | (dolist (theme custom-enabled-themes) 54 | (unless (custom-theme-p theme) 55 | (load-theme theme))) 56 | (custom-set-variables `(custom-enabled-themes (quote ,custom-enabled-themes)))) 57 | 58 | (add-hook 'after-init-hook 'reapply-themes) 59 | 60 | 61 | ;;------------------------------------------------------------------------------ 62 | ;; Toggle between light and dark 63 | ;;------------------------------------------------------------------------------ 64 | (defun light () 65 | "Activate a light color theme." 66 | (interactive) 67 | (color-theme-sanityinc-solarized-light)) 68 | 69 | (defun dark () 70 | "Activate a dark color theme." 71 | (interactive) 72 | (color-theme-sanityinc-solarized-dark)) 73 | 74 | 75 | (provide 'init-themes) 76 | -------------------------------------------------------------------------------- /init-git.el: -------------------------------------------------------------------------------- 1 | (require-package 'magit) 2 | (require-package 'git-gutter-fringe) 3 | (require-package 'git-blame) 4 | (require-package 'git-commit-mode) 5 | (require-package 'git-rebase-mode) 6 | (require-package 'gitignore-mode) 7 | (require-package 'gitconfig-mode) 8 | 9 | (setq-default 10 | magit-save-some-buffers nil 11 | magit-process-popup-time 10 12 | magit-diff-refine-hunk t 13 | magit-completing-read-function 'magit-ido-completing-read) 14 | 15 | (global-set-key [(meta f12)] 'magit-status) 16 | 17 | (after-load 'magit 18 | ;; Don't let magit-status mess up window configurations 19 | ;; http://whattheemacsd.com/setup-magit.el-01.html 20 | (defadvice magit-status (around magit-fullscreen activate) 21 | (window-configuration-to-register :magit-fullscreen) 22 | ad-do-it 23 | (delete-other-windows)) 24 | 25 | (defun magit-quit-session () 26 | "Restores the previous window configuration and kills the magit buffer" 27 | (interactive) 28 | (kill-buffer) 29 | (when (get-register :magit-fullscreen) 30 | (ignore-errors 31 | (jump-to-register :magit-fullscreen)))) 32 | 33 | (define-key magit-status-mode-map (kbd "q") 'magit-quit-session)) 34 | 35 | 36 | ;;; When we start working on git-backed files, use git-wip if available 37 | 38 | (after-load 'vc-git 39 | (global-magit-wip-save-mode) 40 | (diminish 'magit-wip-save-mode)) 41 | 42 | 43 | ;;; Use the fringe version of git-gutter 44 | 45 | (after-load 'git-gutter 46 | (require 'git-gutter-fringe)) 47 | 48 | 49 | (when *is-a-mac* 50 | (after-load 'magit 51 | (add-hook 'magit-mode-hook (lambda () (local-unset-key [(meta h)]))))) 52 | 53 | 54 | 55 | ;; Convenient binding for vc-git-grep 56 | (global-set-key (kbd "C-x v f") 'vc-git-grep) 57 | 58 | 59 | 60 | ;;; git-svn support 61 | 62 | (require-package 'magit-svn) 63 | (after-load 'magit-key-mode 64 | (require 'magit-svn)) 65 | 66 | (after-load 'compile 67 | (dolist (defn (list '(git-svn-updated "^\t[A-Z]\t\\(.*\\)$" 1 nil nil 0 1) 68 | '(git-svn-needs-update "^\\(.*\\): needs update$" 1 nil nil 2 1))) 69 | (add-to-list 'compilation-error-regexp-alist-alist defn) 70 | (add-to-list 'compilation-error-regexp-alist (car defn)))) 71 | 72 | (defvar git-svn--available-commands nil "Cached list of git svn subcommands") 73 | 74 | (defun git-svn (dir) 75 | "Run a git svn subcommand in DIR." 76 | (interactive "DSelect directory: ") 77 | (unless git-svn--available-commands 78 | (setq git-svn--available-commands 79 | (string-all-matches "^ \\([a-z\\-]+\\) +" (shell-command-to-string "git svn help") 1))) 80 | (let* ((default-directory (vc-git-root dir)) 81 | (compilation-buffer-name-function (lambda (major-mode-name) "*git-svn*"))) 82 | (compile (concat "git svn " 83 | (ido-completing-read "git-svn command: " git-svn--available-commands nil t))))) 84 | 85 | 86 | (require-package 'git-messenger) 87 | (global-set-key (kbd "C-x v p") #'git-messenger:popup-message) 88 | 89 | 90 | ;;; github 91 | 92 | (require-package 'yagist) 93 | (require-package 'github-browse-file) 94 | (require-package 'bug-reference-github) 95 | (add-hook 'prog-mode-hook 'bug-reference-prog-mode) 96 | 97 | 98 | 99 | (provide 'init-git) 100 | -------------------------------------------------------------------------------- /init-javascript.el: -------------------------------------------------------------------------------- 1 | (require-package 'json) 2 | (require-package 'json-mode) 3 | (when (>= emacs-major-version 24) 4 | (require-package 'js2-mode) 5 | (require-package 'ac-js2)) 6 | (require-package 'js-comint) 7 | (require-package 'rainbow-delimiters) 8 | (require-package 'coffee-mode) 9 | 10 | (after-load 'js2-mode 11 | (define-key js2-mode-map (kbd "TAB") 'indent-for-tab-command)) 12 | 13 | (defcustom preferred-javascript-mode 14 | (first (remove-if-not #'fboundp '(js2-mode js-mode))) 15 | "Javascript mode to use for .js files." 16 | :type 'symbol 17 | :group 'programming 18 | :options '(js2-mode js-mode)) 19 | (defvar preferred-javascript-indent-level 2) 20 | 21 | ;; Need to first remove from list if present, since elpa adds entries too, which 22 | ;; may be in an arbitrary order 23 | (eval-when-compile (require 'cl)) 24 | (setq auto-mode-alist (cons `("\\.js\\(\\.erb\\)?\\'" . ,preferred-javascript-mode) 25 | (loop for entry in auto-mode-alist 26 | unless (eq preferred-javascript-mode (cdr entry)) 27 | collect entry))) 28 | 29 | 30 | ;; js2-mode 31 | (after-load 'js2-mode 32 | (add-hook 'js2-mode-hook '(lambda () (setq mode-name "JS2")))) 33 | 34 | (setq js2-use-font-lock-faces t 35 | js2-mode-must-byte-compile nil 36 | js2-basic-offset preferred-javascript-indent-level 37 | js2-indent-on-enter-key t 38 | js2-auto-indent-p t 39 | js2-bounce-indent-p nil) 40 | 41 | (after-load 'js2-mode 42 | (js2-imenu-extras-setup)) 43 | 44 | ;; js-mode 45 | (setq js-indent-level preferred-javascript-indent-level) 46 | 47 | 48 | ;; standard javascript-mode 49 | (setq javascript-indent-level preferred-javascript-indent-level) 50 | 51 | (add-to-list 'interpreter-mode-alist (cons "node" preferred-javascript-mode)) 52 | 53 | 54 | ;;; Coffeescript 55 | 56 | (after-load 'coffee-mode 57 | (setq coffee-js-mode preferred-javascript-mode 58 | coffee-tab-width preferred-javascript-indent-level)) 59 | 60 | (add-to-list 'auto-mode-alist '("\\.coffee\\.erb\\'" . coffee-mode)) 61 | 62 | ;; --------------------------------------------------------------------------- 63 | ;; Run and interact with an inferior JS via js-comint.el 64 | ;; --------------------------------------------------------------------------- 65 | 66 | (setq inferior-js-program-command "js") 67 | 68 | (defvar inferior-js-minor-mode-map (make-sparse-keymap)) 69 | (define-key inferior-js-minor-mode-map "\C-x\C-e" 'js-send-last-sexp) 70 | (define-key inferior-js-minor-mode-map "\C-\M-x" 'js-send-last-sexp-and-go) 71 | (define-key inferior-js-minor-mode-map "\C-cb" 'js-send-buffer) 72 | (define-key inferior-js-minor-mode-map "\C-c\C-b" 'js-send-buffer-and-go) 73 | (define-key inferior-js-minor-mode-map "\C-cl" 'js-load-file-and-go) 74 | 75 | (define-minor-mode inferior-js-keys-mode 76 | "Bindings for communicating with an inferior js interpreter." 77 | nil " InfJS" inferior-js-minor-mode-map) 78 | 79 | (dolist (hook '(js2-mode-hook js-mode-hook)) 80 | (add-hook hook 'inferior-js-keys-mode)) 81 | 82 | ;; --------------------------------------------------------------------------- 83 | ;; Alternatively, use skewer-mode 84 | ;; --------------------------------------------------------------------------- 85 | 86 | (when (featurep 'js2-mode) 87 | (require-package 'skewer-mode) 88 | (after-load 'skewer-mode 89 | (add-hook 'skewer-mode-hook 90 | (lambda () (inferior-js-keys-mode -1))))) 91 | 92 | 93 | (provide 'init-javascript) 94 | -------------------------------------------------------------------------------- /init-utils.el: -------------------------------------------------------------------------------- 1 | (defmacro after-load (feature &rest body) 2 | "After FEATURE is loaded, evaluate BODY." 3 | (declare (indent defun)) 4 | `(eval-after-load ,feature 5 | '(progn ,@body))) 6 | 7 | 8 | ;;---------------------------------------------------------------------------- 9 | ;; Handier way to add modes to auto-mode-alist 10 | ;;---------------------------------------------------------------------------- 11 | (defun add-auto-mode (mode &rest patterns) 12 | "Add entries to `auto-mode-alist' to use `MODE' for all given file `PATTERNS'." 13 | (dolist (pattern patterns) 14 | (add-to-list 'auto-mode-alist (cons pattern mode)))) 15 | 16 | 17 | ;;---------------------------------------------------------------------------- 18 | ;; String utilities missing from core emacs 19 | ;;---------------------------------------------------------------------------- 20 | (defun string-all-matches (regex str &optional group) 21 | "Find all matches for `REGEX' within `STR', returning the full match string or group `GROUP'." 22 | (let ((result nil) 23 | (pos 0) 24 | (group (or group 0))) 25 | (while (string-match regex str pos) 26 | (push (match-string group str) result) 27 | (setq pos (match-end group))) 28 | result)) 29 | 30 | (defun string-rtrim (str) 31 | "Remove trailing whitespace from `STR'." 32 | (replace-regexp-in-string "[ \t\n]*$" "" str)) 33 | 34 | 35 | ;;---------------------------------------------------------------------------- 36 | ;; Find the directory containing a given library 37 | ;;---------------------------------------------------------------------------- 38 | (autoload 'find-library-name "find-func") 39 | (defun directory-of-library (library-name) 40 | "Return the directory in which the `LIBRARY-NAME' load file is found." 41 | (file-name-as-directory (file-name-directory (find-library-name library-name)))) 42 | 43 | 44 | ;;---------------------------------------------------------------------------- 45 | ;; Delete the current file 46 | ;;---------------------------------------------------------------------------- 47 | (defun delete-this-file () 48 | "Delete the current file, and kill the buffer." 49 | (interactive) 50 | (or (buffer-file-name) (error "No file is currently being edited")) 51 | (when (yes-or-no-p (format "Really delete '%s'?" 52 | (file-name-nondirectory buffer-file-name))) 53 | (delete-file (buffer-file-name)) 54 | (kill-this-buffer))) 55 | 56 | 57 | ;;---------------------------------------------------------------------------- 58 | ;; Rename the current file 59 | ;;---------------------------------------------------------------------------- 60 | (defun rename-this-file-and-buffer (new-name) 61 | "Renames both current buffer and file it's visiting to NEW-NAME." 62 | (interactive "sNew name: ") 63 | (let ((name (buffer-name)) 64 | (filename (buffer-file-name))) 65 | (unless filename 66 | (error "Buffer '%s' is not visiting a file!" name)) 67 | (if (get-buffer new-name) 68 | (message "A buffer named '%s' already exists!" new-name) 69 | (progn 70 | (rename-file filename new-name 1) 71 | (rename-buffer new-name) 72 | (set-visited-file-name new-name) 73 | (set-buffer-modified-p nil))))) 74 | 75 | ;;---------------------------------------------------------------------------- 76 | ;; Browse current HTML file 77 | ;;---------------------------------------------------------------------------- 78 | (defun browse-current-file () 79 | "Open the current file as a URL using `browse-url'." 80 | (interactive) 81 | (browse-url (concat "file://" (buffer-file-name)))) 82 | 83 | 84 | (provide 'init-utils) 85 | -------------------------------------------------------------------------------- /init-ruby-mode.el: -------------------------------------------------------------------------------- 1 | ;;; Basic ruby setup 2 | (require-package 'ruby-mode) 3 | (require-package 'ruby-hash-syntax) 4 | 5 | (add-auto-mode 'ruby-mode 6 | "Rakefile\\'" "\\.rake\\'" "\\.rxml\\'" 7 | "\\.rjs\\'" ".irbrc\\'" "\\.builder\\'" "\\.ru\\'" 8 | "\\.gemspec\\'" "Gemfile\\'" "Kirkfile\\'") 9 | 10 | (setq ruby-use-encoding-map nil) 11 | 12 | (after-load 'ruby-mode 13 | (define-key ruby-mode-map (kbd "RET") 'reindent-then-newline-and-indent) 14 | (define-key ruby-mode-map (kbd "TAB") 'indent-for-tab-command) 15 | 16 | ;; Stupidly the non-bundled ruby-mode isn't a derived mode of 17 | ;; prog-mode: we run the latter's hooks anyway in that case. 18 | (add-hook 'ruby-mode-hook 19 | (lambda () 20 | (unless (derived-mode-p 'prog-mode) 21 | (run-hooks 'prog-mode-hook))))) 22 | 23 | (add-hook 'ruby-mode-hook 'subword-mode) 24 | 25 | 26 | ;;; Inferior ruby 27 | (require-package 'inf-ruby) 28 | 29 | 30 | 31 | ;;; Ruby compilation 32 | (require-package 'ruby-compilation) 33 | 34 | (after-load 'ruby-mode 35 | (let ((m ruby-mode-map)) 36 | (define-key m [S-f7] 'ruby-compilation-this-buffer) 37 | (define-key m [f7] 'ruby-compilation-this-test) 38 | (define-key m [f6] 'recompile))) 39 | 40 | 41 | 42 | ;;; Robe 43 | (require-package 'robe) 44 | (after-load 'ruby-mode 45 | (add-hook 'ruby-mode-hook 'robe-mode)) 46 | (after-load 'robe 47 | (add-hook 'robe-mode-hook 48 | (lambda () 49 | (add-to-list 'ac-sources 'ac-source-robe) 50 | (set-auto-complete-as-completion-at-point-function)))) 51 | 52 | 53 | 54 | ;;; ri support 55 | (require-package 'yari) 56 | (defalias 'ri 'yari) 57 | 58 | 59 | 60 | ;;; YAML 61 | 62 | (require-package 'yaml-mode) 63 | 64 | 65 | 66 | ;;; ERB 67 | (require-package 'mmm-mode) 68 | (defun sanityinc/ensure-mmm-erb-loaded () 69 | (require 'mmm-erb)) 70 | 71 | (require 'derived) 72 | 73 | (defun sanityinc/set-up-mode-for-erb (mode) 74 | (add-hook (derived-mode-hook-name mode) 'sanityinc/ensure-mmm-erb-loaded) 75 | (mmm-add-mode-ext-class mode "\\.erb\\'" 'erb)) 76 | 77 | (let ((html-erb-modes '(html-mode html-erb-mode nxml-mode))) 78 | (dolist (mode html-erb-modes) 79 | (sanityinc/set-up-mode-for-erb mode) 80 | (mmm-add-mode-ext-class mode "\\.r?html\\(\\.erb\\)?\\'" 'html-js) 81 | (mmm-add-mode-ext-class mode "\\.r?html\\(\\.erb\\)?\\'" 'html-css))) 82 | 83 | (mapc 'sanityinc/set-up-mode-for-erb 84 | '(coffee-mode js-mode js2-mode js3-mode markdown-mode textile-mode)) 85 | 86 | (require-package 'tagedit) 87 | (after-load 'sgml-mode 88 | (tagedit-add-paredit-like-keybindings)) 89 | 90 | (mmm-add-mode-ext-class 'html-erb-mode "\\.jst\\.ejs\\'" 'ejs) 91 | 92 | (add-auto-mode 'html-erb-mode "\\.rhtml\\'" "\\.html\\.erb\\'") 93 | (add-to-list 'auto-mode-alist '("\\.jst\\.ejs\\'" . html-erb-mode)) 94 | (mmm-add-mode-ext-class 'yaml-mode "\\.yaml\\'" 'erb) 95 | 96 | (dolist (mode (list 'js-mode 'js2-mode 'js3-mode)) 97 | (mmm-add-mode-ext-class mode "\\.js\\.erb\\'" 'erb)) 98 | 99 | 100 | ;;---------------------------------------------------------------------------- 101 | ;; Ruby - my convention for heredocs containing SQL 102 | ;;---------------------------------------------------------------------------- 103 | 104 | ;; Needs to run after rinari to avoid clobbering font-lock-keywords? 105 | 106 | ;; (require-package 'mmm-mode) 107 | ;; (eval-after-load 'mmm-mode 108 | ;; '(progn 109 | ;; (mmm-add-classes 110 | ;; '((ruby-heredoc-sql 111 | ;; :submode sql-mode 112 | ;; :front "<<-?[\'\"]?\\(end_sql\\)[\'\"]?" 113 | ;; :save-matches 1 114 | ;; :front-offset (end-of-line 1) 115 | ;; :back "^[ \t]*~1$" 116 | ;; :delimiter-mode nil))) 117 | ;; (mmm-add-mode-ext-class 'ruby-mode "\\.rb\\'" 'ruby-heredoc-sql))) 118 | 119 | ;(add-to-list 'mmm-set-file-name-for-modes 'ruby-mode) 120 | 121 | 122 | 123 | (provide 'init-ruby-mode) 124 | -------------------------------------------------------------------------------- /init-org.el: -------------------------------------------------------------------------------- 1 | (when (< emacs-major-version 24) 2 | (require-package 'org)) 3 | (require-package 'org-fstree) 4 | (when *is-a-mac* 5 | (require-package 'org-mac-link) 6 | (require-package 'org-mac-iCal)) 7 | 8 | 9 | (define-key global-map "\C-cl" 'org-store-link) 10 | (define-key global-map "\C-ca" 'org-agenda) 11 | 12 | ;; Various preferences 13 | (setq org-log-done t 14 | org-completion-use-ido t 15 | org-edit-timestamp-down-means-later t 16 | org-agenda-start-on-weekday nil 17 | org-agenda-span 14 18 | org-agenda-include-diary t 19 | org-agenda-window-setup 'current-window 20 | org-fast-tag-selection-single-key 'expert 21 | org-export-kill-product-buffer-when-displayed t 22 | org-tags-column 80) 23 | 24 | 25 | ; Refile targets include this file and any file contributing to the agenda - up to 5 levels deep 26 | (setq org-refile-targets (quote ((nil :maxlevel . 5) (org-agenda-files :maxlevel . 5)))) 27 | ; Targets start with the file name - allows creating level 1 tasks 28 | (setq org-refile-use-outline-path (quote file)) 29 | ; Targets complete in steps so we start with filename, TAB shows the next level of targets etc 30 | (setq org-outline-path-complete-in-steps t) 31 | 32 | 33 | (setq org-todo-keywords 34 | (quote ((sequence "TODO(t)" "STARTED(s)" "|" "DONE(d!/!)") 35 | (sequence "WAITING(w@/!)" "SOMEDAY(S)" "PROJECT(P@)" "|" "CANCELLED(c@/!)")))) 36 | 37 | 38 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 39 | ;; Org clock 40 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 41 | 42 | ;; Save the running clock and all clock history when exiting Emacs, load it on startup 43 | (setq org-clock-persistence-insinuate t) 44 | (setq org-clock-persist t) 45 | (setq org-clock-in-resume t) 46 | 47 | ;; Change task state to STARTED when clocking in 48 | (setq org-clock-in-switch-to-state "STARTED") 49 | ;; Save clock data and notes in the LOGBOOK drawer 50 | (setq org-clock-into-drawer t) 51 | ;; Removes clocked tasks with 0:00 duration 52 | (setq org-clock-out-remove-zero-time-clocks t) 53 | 54 | ;; Show the clocked-in task - if any - in the header line 55 | (defun sanityinc/show-org-clock-in-header-line () 56 | (setq-default header-line-format '((" " org-mode-line-string " ")))) 57 | 58 | (defun sanityinc/hide-org-clock-from-header-line () 59 | (setq-default header-line-format nil)) 60 | 61 | (add-hook 'org-clock-in-hook 'sanityinc/show-org-clock-in-header-line) 62 | (add-hook 'org-clock-out-hook 'sanityinc/hide-org-clock-from-header-line) 63 | (add-hook 'org-clock-cancel-hook 'sanityinc/hide-org-clock-from-header-line) 64 | 65 | (after-load 'org-clock 66 | (define-key org-clock-mode-line-map [header-line mouse-2] 'org-clock-goto) 67 | (define-key org-clock-mode-line-map [header-line mouse-1] 'org-clock-menu)) 68 | 69 | 70 | ;; ;; Show iCal calendars in the org agenda 71 | ;; (when (and *is-a-mac* (require 'org-mac-iCal nil t)) 72 | ;; (setq org-agenda-include-diary t 73 | ;; org-agenda-custom-commands 74 | ;; '(("I" "Import diary from iCal" agenda "" 75 | ;; ((org-agenda-mode-hook #'org-mac-iCal))))) 76 | 77 | ;; (add-hook 'org-agenda-cleanup-fancy-diary-hook 78 | ;; (lambda () 79 | ;; (goto-char (point-min)) 80 | ;; (save-excursion 81 | ;; (while (re-search-forward "^[a-z]" nil t) 82 | ;; (goto-char (match-beginning 0)) 83 | ;; (insert "0:00-24:00 "))) 84 | ;; (while (re-search-forward "^ [a-z]" nil t) 85 | ;; (goto-char (match-beginning 0)) 86 | ;; (save-excursion 87 | ;; (re-search-backward "^[0-9]+:[0-9]+-[0-9]+:[0-9]+ " nil t)) 88 | ;; (insert (match-string 0)))))) 89 | 90 | 91 | (after-load 'org 92 | (define-key org-mode-map (kbd "C-M-") 'org-up-element) 93 | (when *is-a-mac* 94 | (define-key org-mode-map (kbd "M-h") nil)) 95 | (define-key org-mode-map (kbd "C-M-") 'org-up-element) 96 | (when *is-a-mac* 97 | (autoload 'omlg-grab-link "org-mac-link") 98 | (define-key org-mode-map (kbd "C-c g") 'omlg-grab-link))) 99 | 100 | (provide 'init-org) 101 | -------------------------------------------------------------------------------- /init.el: -------------------------------------------------------------------------------- 1 | ;;; This file bootstraps the configuration, which is divided into 2 | ;;; a number of other files. 3 | 4 | (add-to-list 'load-path user-emacs-directory) 5 | (require 'init-benchmarking) ;; Measure startup time 6 | 7 | ;;---------------------------------------------------------------------------- 8 | ;; Which functionality to enable (use t or nil for true and false) 9 | ;;---------------------------------------------------------------------------- 10 | (defconst *spell-check-support-enabled* nil) 11 | (defconst *is-a-mac* (eq system-type 'darwin)) 12 | (defconst *is-cocoa-emacs* (and *is-a-mac* (eq window-system 'ns))) 13 | 14 | ;;---------------------------------------------------------------------------- 15 | ;; Bootstrap config 16 | ;;---------------------------------------------------------------------------- 17 | (require 'init-compat) 18 | (require 'init-utils) 19 | (require 'init-site-lisp) ;; Must come before elpa, as it may provide package.el 20 | (require 'init-elpa) ;; Machinery for installing required packages 21 | (require 'init-exec-path) ;; Set up $PATH 22 | 23 | ;;---------------------------------------------------------------------------- 24 | ;; Load configs for specific features and modes 25 | ;;---------------------------------------------------------------------------- 26 | 27 | (require-package 'wgrep) 28 | (require-package 'project-local-variables) 29 | (require-package 'diminish) 30 | (require-package 'scratch) 31 | (require-package 'mwe-log-commands) 32 | 33 | (require 'init-frame-hooks) 34 | (require 'init-xterm) 35 | (require 'init-themes) 36 | (require 'init-osx-keys) 37 | (require 'init-gui-frames) 38 | (require 'init-maxframe) 39 | (require 'init-proxies) 40 | (require 'init-dired) 41 | (require 'init-isearch) 42 | (require 'init-uniquify) 43 | (require 'init-ibuffer) 44 | (require 'init-flycheck) 45 | 46 | (require 'init-recentf) 47 | (require 'init-ido) 48 | (require 'init-hippie-expand) 49 | (require 'init-auto-complete) 50 | (require 'init-windows) 51 | (require 'init-sessions) 52 | (require 'init-fonts) 53 | (require 'init-mmm) 54 | (require 'init-growl) 55 | 56 | (require 'init-editing-utils) 57 | 58 | (require 'init-darcs) 59 | (require 'init-git) 60 | 61 | (require 'init-crontab) 62 | (require 'init-textile) 63 | (require 'init-markdown) 64 | (require 'init-csv) 65 | (require 'init-erlang) 66 | (require 'init-javascript) 67 | (require 'init-php) 68 | (require 'init-org) 69 | (require 'init-nxml) 70 | (require 'init-css) 71 | (require 'init-haml) 72 | (require 'init-python-mode) 73 | (require 'init-haskell) 74 | (require 'init-ruby-mode) 75 | (require 'init-rails) 76 | (require 'init-sql) 77 | 78 | (require 'init-paredit) 79 | (require 'init-lisp) 80 | (require 'init-slime) 81 | (require 'init-clojure) 82 | (require 'init-common-lisp) 83 | 84 | (when *spell-check-support-enabled* 85 | (require 'init-spelling)) 86 | 87 | (require 'init-marmalade) 88 | (require 'init-misc) 89 | 90 | ;; Extra packages which don't require any configuration 91 | 92 | (require-package 'gnuplot) 93 | (require-package 'lua-mode) 94 | (require-package 'htmlize) 95 | (require-package 'dsvn) 96 | (when *is-a-mac* 97 | (require-package 'osx-location)) 98 | (require-package 'regex-tool) 99 | 100 | ;;---------------------------------------------------------------------------- 101 | ;; Allow access from emacsclient 102 | ;;---------------------------------------------------------------------------- 103 | (require 'server) 104 | (unless (server-running-p) 105 | (server-start)) 106 | 107 | 108 | ;;---------------------------------------------------------------------------- 109 | ;; Variables configured via the interactive 'customize' interface 110 | ;;---------------------------------------------------------------------------- 111 | (setq custom-file (expand-file-name "custom.el" user-emacs-directory)) 112 | (when (file-exists-p custom-file) 113 | (load custom-file)) 114 | 115 | 116 | ;;---------------------------------------------------------------------------- 117 | ;; Allow users to provide an optional "init-local" containing personal settings 118 | ;;---------------------------------------------------------------------------- 119 | (require 'init-local nil t) 120 | 121 | 122 | ;;---------------------------------------------------------------------------- 123 | ;; Locales (setting them earlier in this file doesn't work in X) 124 | ;;---------------------------------------------------------------------------- 125 | (require 'init-locales) 126 | 127 | (message "init completed in %.2fms" 128 | (sanityinc/time-subtract-millis (current-time) before-init-time)) 129 | 130 | ;; Local Variables: 131 | ;; coding: utf-8 132 | ;; no-byte-compile: t 133 | ;; End: 134 | -------------------------------------------------------------------------------- /init-lisp.el: -------------------------------------------------------------------------------- 1 | (require-package 'elisp-slime-nav) 2 | (dolist (hook '(emacs-lisp-mode-hook ielm-mode-hook)) 3 | (add-hook hook 'elisp-slime-nav-mode)) 4 | 5 | (require-package 'lively) 6 | 7 | (require-package 'pretty-mode) 8 | (autoload 'turn-on-pretty-mode "pretty-mode") 9 | 10 | ;; ---------------------------------------------------------------------------- 11 | ;; Hippie-expand 12 | ;; ---------------------------------------------------------------------------- 13 | (defun set-up-hippie-expand-for-elisp () 14 | "Locally set `hippie-expand' completion functions for use with Emacs Lisp." 15 | (make-local-variable 'hippie-expand-try-functions-list) 16 | (add-to-list 'hippie-expand-try-functions-list 'try-complete-lisp-symbol t) 17 | (add-to-list 'hippie-expand-try-functions-list 'try-complete-lisp-symbol-partially t)) 18 | 19 | 20 | ;; ---------------------------------------------------------------------------- 21 | ;; Automatic byte compilation 22 | ;; ---------------------------------------------------------------------------- 23 | 24 | (require-package 'auto-compile) 25 | (auto-compile-on-save-mode 1) 26 | (auto-compile-on-load-mode 1) 27 | 28 | ;; ---------------------------------------------------------------------------- 29 | ;; Highlight current sexp 30 | ;; ---------------------------------------------------------------------------- 31 | 32 | (require-package 'hl-sexp) 33 | 34 | ;; Prevent flickery behaviour due to hl-sexp-mode unhighlighting before each command 35 | (after-load 'hl-sexp 36 | (defadvice hl-sexp-mode (after unflicker (&optional turn-on) activate) 37 | (when turn-on 38 | (remove-hook 'pre-command-hook #'hl-sexp-unhighlight)))) 39 | 40 | 41 | 42 | ;;; Support byte-compilation in a sub-process, as 43 | ;;; required by highlight-cl 44 | 45 | (defun sanityinc/byte-compile-file-batch (filename) 46 | "Byte-compile FILENAME in batch mode, ie. a clean sub-process." 47 | (interactive "fFile to byte-compile in batch mode: ") 48 | (let ((emacs (car command-line-args))) 49 | (compile 50 | (concat 51 | emacs " " 52 | (mapconcat 53 | 'shell-quote-argument 54 | (list "-Q" "-batch" "-f" "batch-byte-compile" filename) 55 | " "))))) 56 | 57 | 58 | ;; ---------------------------------------------------------------------------- 59 | ;; Enable desired features for all lisp modes 60 | ;; ---------------------------------------------------------------------------- 61 | (require-package 'rainbow-delimiters) 62 | (require-package 'redshank) 63 | (after-load 'redshank 64 | (diminish 'redshank-mode)) 65 | 66 | 67 | (defun sanityinc/lisp-setup () 68 | "Enable features useful in any Lisp mode." 69 | (rainbow-delimiters-mode t) 70 | (enable-paredit-mode) 71 | (turn-on-eldoc-mode) 72 | (redshank-mode)) 73 | 74 | (defun sanityinc/emacs-lisp-setup () 75 | "Enable features useful when working with elisp." 76 | (elisp-slime-nav-mode t) 77 | (set-up-hippie-expand-for-elisp) 78 | (ac-emacs-lisp-mode-setup)) 79 | 80 | (defconst sanityinc/elispy-modes 81 | '(emacs-lisp-mode ielm-mode) 82 | "Major modes relating to elisp.") 83 | 84 | (defconst sanityinc/lispy-modes 85 | (append sanityinc/elispy-modes 86 | '(lisp-mode inferior-lisp-mode lisp-interaction-mode)) 87 | "All lispy major modes.") 88 | 89 | (require 'derived) 90 | 91 | (dolist (hook (mapcar #'derived-mode-hook-name sanityinc/lispy-modes)) 92 | (add-hook hook 'sanityinc/lisp-setup)) 93 | 94 | (dolist (hook (mapcar #'derived-mode-hook-name sanityinc/elispy-modes)) 95 | (add-hook hook 'sanityinc/emacs-lisp-setup)) 96 | 97 | (defun sanityinc/maybe-check-parens () 98 | "Run `check-parens' if this is a lispy mode." 99 | (when (memq major-mode sanityinc/lispy-modes) 100 | (check-parens))) 101 | 102 | (add-hook 'after-save-hook #'sanityinc/maybe-check-parens) 103 | 104 | (require-package 'eldoc-eval) 105 | (require 'eldoc-eval) 106 | 107 | (add-to-list 'auto-mode-alist '("\\.emacs-project\\'" . emacs-lisp-mode)) 108 | (add-to-list 'auto-mode-alist '("archive-contents\\'" . emacs-lisp-mode)) 109 | 110 | (define-key emacs-lisp-mode-map (kbd "C-x C-a") 'pp-macroexpand-last-sexp) 111 | (define-key emacs-lisp-mode-map (kbd "C-x C-e") 'pp-eval-last-sexp) 112 | 113 | (require-package 'cl-lib-highlight) 114 | (cl-lib-highlight-initialize) 115 | 116 | ;; ---------------------------------------------------------------------------- 117 | ;; Delete .elc files when reverting the .el from VC or magit 118 | ;; ---------------------------------------------------------------------------- 119 | 120 | ;; When .el files are open, we can intercept when they are modified 121 | ;; by VC or magit in order to remove .elc files that are likely to 122 | ;; be out of sync. 123 | 124 | ;; This is handy while actively working on elisp files, though 125 | ;; obviously it doesn't ensure that unopened files will also have 126 | ;; their .elc counterparts removed - VC hooks would be necessary for 127 | ;; that. 128 | 129 | (defvar sanityinc/vc-reverting nil 130 | "Whether or not VC or Magit is currently reverting buffers.") 131 | 132 | (defadvice revert-buffer (after sanityinc/maybe-remove-elc activate) 133 | "If reverting from VC, delete any .elc file that will now be out of sync." 134 | (when sanityinc/vc-reverting 135 | (when (and (eq 'emacs-lisp-mode major-mode) 136 | buffer-file-name 137 | (string= "el" (file-name-extension buffer-file-name))) 138 | (let ((elc (concat buffer-file-name "c"))) 139 | (when (file-exists-p elc) 140 | (message "Removing out-of-sync elc file %s" (file-name-nondirectory elc)) 141 | (delete-file elc)))))) 142 | 143 | (defadvice magit-revert-buffers (around sanityinc/reverting activate) 144 | (let ((sanityinc/vc-reverting t)) 145 | ad-do-it)) 146 | (defadvice vc-revert-buffer-internal (around sanityinc/reverting activate) 147 | (let ((sanityinc/vc-reverting t)) 148 | ad-do-it)) 149 | 150 | 151 | 152 | (require-package 'macrostep) 153 | 154 | (after-load 'lisp-mode 155 | (define-key emacs-lisp-mode-map (kbd "C-c e") 'macrostep-expand)) 156 | 157 | 158 | 159 | (provide 'init-lisp) 160 | -------------------------------------------------------------------------------- /init-editing-utils.el: -------------------------------------------------------------------------------- 1 | (require-package 'unfill) 2 | (require-package 'whole-line-or-region) 3 | 4 | (when (fboundp 'electric-pair-mode) 5 | (setq-default electric-pair-mode 1)) 6 | 7 | ;;---------------------------------------------------------------------------- 8 | ;; Some basic preferences 9 | ;;---------------------------------------------------------------------------- 10 | (setq-default 11 | blink-cursor-delay 0 12 | blink-cursor-interval 0.4 13 | bookmark-default-file (expand-file-name ".bookmarks.el" user-emacs-directory) 14 | buffers-menu-max-size 30 15 | case-fold-search t 16 | column-number-mode t 17 | compilation-scroll-output t 18 | delete-selection-mode t 19 | ediff-split-window-function 'split-window-horizontally 20 | ediff-window-setup-function 'ediff-setup-windows-plain 21 | grep-highlight-matches t 22 | grep-scroll-output t 23 | indent-tabs-mode nil 24 | line-spacing 0.2 25 | make-backup-files nil 26 | mouse-yank-at-point t 27 | save-interprogram-paste-before-kill t 28 | scroll-preserve-screen-position 'always 29 | set-mark-command-repeat-pop t 30 | show-trailing-whitespace t 31 | tooltip-delay 1.5 32 | truncate-lines nil 33 | truncate-partial-width-windows nil 34 | visible-bell t) 35 | 36 | (when *is-a-mac* 37 | (setq-default locate-command "mdfind")) 38 | 39 | (global-auto-revert-mode) 40 | (setq global-auto-revert-non-file-buffers t 41 | auto-revert-verbose nil) 42 | 43 | ;; But don't show trailing whitespace in SQLi, inf-ruby etc. 44 | (dolist (hook '(term-mode-hook comint-mode-hook compilation-mode-hook twittering-mode-hook)) 45 | (add-hook hook 46 | (lambda () (setq show-trailing-whitespace nil)))) 47 | 48 | 49 | (require-package 'whitespace-cleanup-mode) 50 | (global-whitespace-cleanup-mode t) 51 | 52 | (transient-mark-mode t) 53 | 54 | (global-set-key (kbd "RET") 'newline-and-indent) 55 | 56 | (after-load 'subword 57 | (diminish 'subword-mode)) 58 | 59 | 60 | (require-package 'undo-tree) 61 | (global-undo-tree-mode) 62 | (diminish 'undo-tree-mode) 63 | 64 | ;;---------------------------------------------------------------------------- 65 | ;; Zap *up* to char is a handy pair for zap-to-char 66 | ;;---------------------------------------------------------------------------- 67 | (autoload 'zap-up-to-char "misc" "Kill up to, but not including ARGth occurrence of CHAR.") 68 | (global-set-key (kbd "M-Z") 'zap-up-to-char) 69 | 70 | ;;---------------------------------------------------------------------------- 71 | ;; Don't disable narrowing commands 72 | ;;---------------------------------------------------------------------------- 73 | (put 'narrow-to-region 'disabled nil) 74 | (put 'narrow-to-page 'disabled nil) 75 | (put 'narrow-to-defun 'disabled nil) 76 | 77 | ;;---------------------------------------------------------------------------- 78 | ;; Show matching parens 79 | ;;---------------------------------------------------------------------------- 80 | (require-package 'mic-paren) 81 | (paren-activate) ; activating mic-paren 82 | 83 | ;;---------------------------------------------------------------------------- 84 | ;; Expand region 85 | ;;---------------------------------------------------------------------------- 86 | (require-package 'expand-region) 87 | (global-set-key (kbd "C-=") 'er/expand-region) 88 | 89 | 90 | ;;---------------------------------------------------------------------------- 91 | ;; Don't disable case-change functions 92 | ;;---------------------------------------------------------------------------- 93 | (put 'upcase-region 'disabled nil) 94 | (put 'downcase-region 'disabled nil) 95 | 96 | 97 | ;;---------------------------------------------------------------------------- 98 | ;; Rectangle selections, and overwrite text when the selection is active 99 | ;;---------------------------------------------------------------------------- 100 | (cua-selection-mode t) ; for rectangles, CUA is nice 101 | 102 | 103 | ;;---------------------------------------------------------------------------- 104 | ;; Handy key bindings 105 | ;;---------------------------------------------------------------------------- 106 | ;; To be able to M-x without meta 107 | (global-set-key (kbd "C-x C-m") 'execute-extended-command) 108 | 109 | ;; Vimmy alternatives to M-^ and C-u M-^ 110 | (global-set-key (kbd "C-c j") 'join-line) 111 | (global-set-key (kbd "C-c J") (lambda () (interactive) (join-line 1))) 112 | 113 | (global-set-key (kbd "C-.") 'set-mark-command) 114 | (global-set-key (kbd "C-x C-.") 'pop-global-mark) 115 | 116 | (require-package 'ace-jump-mode) 117 | (global-set-key (kbd "C-;") 'ace-jump-mode) 118 | (global-set-key (kbd "C-:") 'ace-jump-word-mode) 119 | 120 | 121 | (require-package 'multiple-cursors) 122 | ;; multiple-cursors 123 | (global-set-key (kbd "C-<") 'mc/mark-previous-like-this) 124 | (global-set-key (kbd "C->") 'mc/mark-next-like-this) 125 | (global-set-key (kbd "C-+") 'mc/mark-next-like-this) 126 | (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this) 127 | ;; From active region to multiple cursors: 128 | (global-set-key (kbd "C-c c r") 'set-rectangular-region-anchor) 129 | (global-set-key (kbd "C-c c c") 'mc/edit-lines) 130 | (global-set-key (kbd "C-c c e") 'mc/edit-ends-of-lines) 131 | (global-set-key (kbd "C-c c a") 'mc/edit-beginnings-of-lines) 132 | 133 | 134 | (defun duplicate-region (beg end) 135 | "Insert a copy of the current region after the region." 136 | (interactive "r") 137 | (save-excursion 138 | (goto-char end) 139 | (insert (buffer-substring beg end)))) 140 | 141 | (defun duplicate-line-or-region (prefix) 142 | "Duplicate either the current line or any current region." 143 | (interactive "*p") 144 | (whole-line-or-region-call-with-region 'duplicate-region prefix t)) 145 | 146 | (global-set-key (kbd "C-c p") 'duplicate-line-or-region) 147 | 148 | ;; Train myself to use M-f and M-b instead 149 | (global-unset-key [M-left]) 150 | (global-unset-key [M-right]) 151 | 152 | 153 | 154 | (defun kill-back-to-indentation () 155 | "Kill from point back to the first non-whitespace character on the line." 156 | (interactive) 157 | (let ((prev-pos (point))) 158 | (back-to-indentation) 159 | (kill-region (point) prev-pos))) 160 | 161 | (global-set-key (kbd "C-M-") 'kill-back-to-indentation) 162 | 163 | 164 | ;;---------------------------------------------------------------------------- 165 | ;; Page break lines 166 | ;;---------------------------------------------------------------------------- 167 | (require-package 'page-break-lines) 168 | (global-page-break-lines-mode) 169 | (diminish 'page-break-lines-mode) 170 | 171 | ;;---------------------------------------------------------------------------- 172 | ;; Fill column indicator 173 | ;;---------------------------------------------------------------------------- 174 | (when (eval-when-compile (> emacs-major-version 23)) 175 | (require-package 'fill-column-indicator) 176 | (defun sanityinc/prog-mode-fci-settings () 177 | (turn-on-fci-mode) 178 | (when show-trailing-whitespace 179 | (set (make-local-variable 'whitespace-style) '(face trailing)) 180 | (whitespace-mode 1))) 181 | 182 | ;;(add-hook 'prog-mode-hook 'sanityinc/prog-mode-fci-settings) 183 | 184 | (defun sanityinc/fci-enabled-p () 185 | (and (boundp 'fci-mode) fci-mode)) 186 | 187 | (defvar sanityinc/fci-mode-suppressed nil) 188 | (defadvice popup-create (before suppress-fci-mode activate) 189 | "Suspend fci-mode while popups are visible" 190 | (let ((fci-enabled (sanityinc/fci-enabled-p))) 191 | (when fci-enabled 192 | (set (make-local-variable 'sanityinc/fci-mode-suppressed) fci-enabled) 193 | (turn-off-fci-mode)))) 194 | (defadvice popup-delete (after restore-fci-mode activate) 195 | "Restore fci-mode when all popups have closed" 196 | (when (and sanityinc/fci-mode-suppressed 197 | (null popup-instances)) 198 | (setq sanityinc/fci-mode-suppressed nil) 199 | (turn-on-fci-mode))) 200 | 201 | ;; Regenerate fci-mode line images after switching themes 202 | (defadvice enable-theme (after recompute-fci-face activate) 203 | (dolist (buffer (buffer-list)) 204 | (with-current-buffer buffer 205 | (when (sanityinc/fci-enabled-p) 206 | (turn-on-fci-mode)))))) 207 | 208 | 209 | ;;---------------------------------------------------------------------------- 210 | ;; Shift lines up and down with M-up and M-down. When paredit is enabled, 211 | ;; it will use those keybindings. For this reason, you might prefer to 212 | ;; use M-S-up and M-S-down, which will work even in lisp modes. 213 | ;;---------------------------------------------------------------------------- 214 | (require-package 'move-text) 215 | (move-text-default-bindings) 216 | (global-set-key [M-S-up] 'move-text-up) 217 | (global-set-key [M-S-down] 'move-text-down) 218 | 219 | ;;---------------------------------------------------------------------------- 220 | ;; Fix backward-up-list to understand quotes, see http://bit.ly/h7mdIL 221 | ;;---------------------------------------------------------------------------- 222 | (defun backward-up-sexp (arg) 223 | "Jump up to the start of the ARG'th enclosing sexp." 224 | (interactive "p") 225 | (let ((ppss (syntax-ppss))) 226 | (cond ((elt ppss 3) 227 | (goto-char (elt ppss 8)) 228 | (backward-up-sexp (1- arg))) 229 | ((backward-up-list arg))))) 230 | 231 | (global-set-key [remap backward-up-list] 'backward-up-sexp) ; C-M-u, C-M-up 232 | 233 | 234 | ;;---------------------------------------------------------------------------- 235 | ;; Cut/copy the current line if no region is active 236 | ;;---------------------------------------------------------------------------- 237 | (whole-line-or-region-mode t) 238 | (diminish 'whole-line-or-region-mode) 239 | (make-variable-buffer-local 'whole-line-or-region-mode) 240 | 241 | (defun suspend-mode-during-cua-rect-selection (mode-name) 242 | "Add an advice to suspend `MODE-NAME' while selecting a CUA rectangle." 243 | (let ((flagvar (intern (format "%s-was-active-before-cua-rectangle" mode-name))) 244 | (advice-name (intern (format "suspend-%s" mode-name)))) 245 | (eval-after-load 'cua-rect 246 | `(progn 247 | (defvar ,flagvar nil) 248 | (make-variable-buffer-local ',flagvar) 249 | (defadvice cua--activate-rectangle (after ,advice-name activate) 250 | (setq ,flagvar (and (boundp ',mode-name) ,mode-name)) 251 | (when ,flagvar 252 | (,mode-name 0))) 253 | (defadvice cua--deactivate-rectangle (after ,advice-name activate) 254 | (when ,flagvar 255 | (,mode-name 1))))))) 256 | 257 | (suspend-mode-during-cua-rect-selection 'whole-line-or-region-mode) 258 | 259 | 260 | 261 | 262 | (defun sanityinc/open-line-with-reindent (n) 263 | "A version of `open-line' which reindents the start and end positions. 264 | If there is a fill prefix and/or a `left-margin', insert them 265 | on the new line if the line would have been blank. 266 | With arg N, insert N newlines." 267 | (interactive "*p") 268 | (let* ((do-fill-prefix (and fill-prefix (bolp))) 269 | (do-left-margin (and (bolp) (> (current-left-margin) 0))) 270 | (loc (point-marker)) 271 | ;; Don't expand an abbrev before point. 272 | (abbrev-mode nil)) 273 | (delete-horizontal-space t) 274 | (newline n) 275 | (indent-according-to-mode) 276 | (when (eolp) 277 | (delete-horizontal-space t)) 278 | (goto-char loc) 279 | (while (> n 0) 280 | (cond ((bolp) 281 | (if do-left-margin (indent-to (current-left-margin))) 282 | (if do-fill-prefix (insert-and-inherit fill-prefix)))) 283 | (forward-line 1) 284 | (setq n (1- n))) 285 | (goto-char loc) 286 | (end-of-line) 287 | (indent-according-to-mode))) 288 | 289 | (global-set-key (kbd "C-o") 'sanityinc/open-line-with-reindent) 290 | 291 | 292 | ;;---------------------------------------------------------------------------- 293 | ;; Random line sorting 294 | ;;---------------------------------------------------------------------------- 295 | (defun sort-lines-random (beg end) 296 | "Sort lines in region randomly." 297 | (interactive "r") 298 | (save-excursion 299 | (save-restriction 300 | (narrow-to-region beg end) 301 | (goto-char (point-min)) 302 | (let ;; To make `end-of-line' and etc. to ignore fields. 303 | ((inhibit-field-text-motion t)) 304 | (sort-subr nil 'forward-line 'end-of-line nil nil 305 | (lambda (s1 s2) (eq (random 2) 0))))))) 306 | 307 | 308 | 309 | (require-package 'visual-regexp) 310 | (global-set-key [remap query-replace-regexp] 'vr/query-replace) 311 | (global-set-key [remap replace-regexp] 'vr/replace) 312 | 313 | 314 | 315 | (when (executable-find "ag") 316 | (require-package 'ag) 317 | (require-package 'wgrep-ag) 318 | (setq-default ag-highlight-search t)) 319 | 320 | 321 | 322 | (require-package 'highlight-escape-sequences) 323 | (hes-mode) 324 | 325 | 326 | (provide 'init-editing-utils) 327 | -------------------------------------------------------------------------------- /site-lisp/todochiku-icons/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The Crystal Project are released under LGPL. 2 | 3 | The Emacs Icon was Created by Andrew Zhilin, and I assume was Released 4 | under the GPL. 5 | 6 | GNU General Public License. 7 | 8 | 0. This License Agreement applies to any software library or other 9 | program which contains a notice placed by the copyright holder or 10 | other authorized party saying it may be distributed under the terms 11 | of this Lesser General Public License (also called "this 12 | License"). Each licensee is addressed as "you". 13 | 14 | A "library" means a collection of software functions and/or data 15 | prepared so as to be conveniently linked with application 16 | programs (which use some of those functions and data) to form 17 | executables. 18 | 19 | The "Library", below, refers to any such software library or 20 | work which has been distributed under these terms. A "work based 21 | on the Library" means either the Library or any derivative work 22 | under copyright law: that is to say, a work containing the 23 | Library or a portion of it, either verbatim or with 24 | modifications and/or translated straightforwardly into another 25 | language. (Hereinafter, translation is included without 26 | limitation in the term "modification".) 27 | 28 | "Source code" for a work means the preferred form of the work 29 | for making modifications to it. For a library, complete source 30 | code means all the source code for all modules it contains, plus 31 | any associated interface definition files, plus the scripts used 32 | to control compilation and installation of the library. 33 | 34 | Activities other than copying, distribution and modification are 35 | not covered by this License; they are outside its scope. The act 36 | of running a program using the Library is not restricted, and 37 | output from such a program is covered only if its contents 38 | constitute a work based on the Library (independent of the use 39 | of the Library in a tool for writing it). Whether that is true 40 | depends on what the Library does and what the program that uses 41 | the Library does. 42 | 43 | 44 | 1. You may copy and distribute verbatim copies of the Library's 45 | complete source code as you receive it, in any medium, provided 46 | that you conspicuously and appropriately publish on each copy an 47 | appropriate copyright notice and disclaimer of warranty; keep 48 | intact all the notices that refer to this License and to the 49 | absence of any warranty; and distribute a copy of this License 50 | along with the Library. 51 | 52 | You may charge a fee for the physical act of transferring a 53 | copy, and you may at your option offer warranty protection in 54 | exchange for a fee. 55 | 56 | 57 | 2. You may modify your copy or copies of the Library or any portion 58 | of it, thus forming a work based on the Library, and copy and 59 | distribute such modifications or work under the terms of Section 1 60 | above, provided that you also meet all of these conditions: 61 | 62 | 1. The modified work must itself be a software library. 63 | 64 | 2. You must cause the files modified to carry prominent 65 | notices stating that you changed the files and the date of 66 | any change. 67 | 68 | 3. You must cause the whole of the work to be licensed at no 69 | charge to all third parties under the terms of this License. 70 | 71 | 4. If a facility in the modified Library refers to a function 72 | or a table of data to be supplied by an application program 73 | that uses the facility, other than as an argument passed when 74 | the facility is invoked, then you must make a good faith 75 | effort to ensure that, in the event an application does not 76 | supply such function or table, the facility still operates, 77 | and performs whatever part of its purpose remains meaningful. 78 | 79 | (For example, a function in a library to compute square roots 80 | has a purpose that is entirely well-defined independent of the 81 | application. Therefore, Subsection 2d requires that any 82 | application-supplied function or table used by this function 83 | must be optional: if the application does not supply it, the 84 | square root function must still compute square roots.) 85 | 86 | These requirements apply to the modified work as a whole. If 87 | identifiable sections of that work are not derived from the 88 | Library, and can be reasonably considered independent and 89 | separate works in themselves, then this License, and its terms, 90 | do not apply to those sections when you distribute them as 91 | separate works. But when you distribute the same sections as 92 | part of a whole which is a work based on the Library, the 93 | distribution of the whole must be on the terms of this License, 94 | whose permissions for other licensees extend to the entire 95 | whole, and thus to each and every part regardless of who wrote 96 | it. 97 | 98 | Thus, it is not the intent of this section to claim rights or 99 | contest your rights to work written entirely by you; rather, the 100 | intent is to exercise the right to control the distribution of 101 | derivative or collective works based on the Library. 102 | 103 | In addition, mere aggregation of another work not based on the 104 | Library with the Library (or with a work based on the Library) 105 | on a volume of a storage or distribution medium does not bring 106 | the other work under the scope of this License. 107 | 108 | 3. You may opt to apply the terms of the ordinary GNU General 109 | Public License instead of this License to a given copy of the 110 | Library. To do this, you must alter all the notices that refer to 111 | this License, so that they refer to the ordinary GNU General Public 112 | License, version 2, instead of to this License. (If a newer version 113 | than version 2 of the ordinary GNU General Public License has 114 | appeared, then you can specify that version instead if you wish.) 115 | Do not make any other change in these notices. 116 | 117 | Once this change is made in a given copy, it is irreversible for 118 | that copy, so the ordinary GNU General Public License applies to 119 | all subsequent copies and derivative works made from that copy. 120 | 121 | This option is useful when you wish to copy part of the code of 122 | the Library into a program that is not a library. 123 | 124 | 4. You may copy and distribute the Library (or a portion or 125 | derivative of it, under Section 2) in object code or executable 126 | form under the terms of Sections 1 and 2 above provided that you 127 | accompany it with the complete corresponding machine-readable 128 | source code, which must be distributed under the terms of Sections 129 | 1 and 2 above on a medium customarily used for software 130 | interchange. 131 | 132 | If distribution of object code is made by offering access to 133 | copy from a designated place, then offering equivalent access to 134 | copy the source code from the same place satisfies the 135 | requirement to distribute the source code, even though third 136 | parties are not compelled to copy the source along with the 137 | object code. 138 | 139 | 5. A program that contains no derivative of any portion of the 140 | Library, but is designed to work with the Library by being compiled 141 | or linked with it, is called a "work that uses the Library". Such a 142 | work, in isolation, is not a derivative work of the Library, and 143 | therefore falls outside the scope of this License. 144 | 145 | However, linking a "work that uses the Library" with the Library 146 | creates an executable that is a derivative of the Library 147 | (because it contains portions of the Library), rather than a 148 | "work that uses the library". The executable is therefore 149 | covered by this License. Section 6 states terms for distribution 150 | of such executables. 151 | 152 | When a "work that uses the Library" uses material from a header 153 | file that is part of the Library, the object code for the work 154 | may be a derivative work of the Library even though the source 155 | code is not. Whether this is true is especially significant if 156 | the work can be linked without the Library, or if the work is 157 | itself a library. The threshold for this to be true is not 158 | precisely defined by law. 159 | 160 | If such an object file uses only numerical parameters, data 161 | structure layouts and accessors, and small macros and small 162 | inline functions (ten lines or less in length), then the use of 163 | the object file is unrestricted, regardless of whether it is 164 | legally a derivative work. (Executables containing this object 165 | code plus portions of the Library will still fall under Section 166 | 6.) 167 | 168 | Otherwise, if the work is a derivative of the Library, you may 169 | distribute the object code for the work under the terms of 170 | Section 6. Any executables containing that work also fall under 171 | Section 6, whether or not they are linked directly with the 172 | Library itself. 173 | 174 | 6. As an exception to the Sections above, you may also combine or 175 | link a "work that uses the Library" with the Library to produce a 176 | work containing portions of the Library, and distribute that work 177 | under terms of your choice, provided that the terms permit 178 | modification of the work for the customer's own use and reverse 179 | engineering for debugging such modifications. 180 | 181 | You must give prominent notice with each copy of the work that 182 | the Library is used in it and that the Library and its use are 183 | covered by this License. You must supply a copy of this 184 | License. If the work during execution displays copyright 185 | notices, you must include the copyright notice for the Library 186 | among them, as well as a reference directing the user to the 187 | copy of this License. Also, you must do one of these things: 188 | 189 | 1. Accompany the work with the complete corresponding 190 | machine-readable source code for the Library including 191 | whatever changes were used in the work (which must be 192 | distributed under Sections 1 and 2 above); and, if the work 193 | is an executable linked with the Library, with the complete 194 | machine-readable "work that uses the Library", as object code 195 | and/or source code, so that the user can modify the Library 196 | and then relink to produce a modified executable containing 197 | the modified Library. (It is understood that the user who 198 | changes the contents of definitions files in the Library will 199 | not necessarily be able to recompile the application to use 200 | the modified definitions.) . 201 | 202 | 2. Use a suitable shared library mechanism for linking with 203 | the Library. A suitable mechanism is one that (1) uses at run 204 | time a copy of the library already present on the user's 205 | computer system, rather than copying library functions into 206 | the executable, and (2) will operate properly with a modified 207 | version of the library, if the user installs one, as long as 208 | the modified version is interface-compatible with the version 209 | that the work was made with. 210 | 211 | 3. Accompany the work with a written offer, valid for at 212 | least three years, to give the same user the materials 213 | specified in Subsection 6a, above, for a charge no more than 214 | the cost of performing this distribution. 215 | 216 | 4. If distribution of the work is made by offering access to 217 | copy from a designated place, offer equivalent access to copy 218 | the above specified materials from the same place. 219 | 220 | 5. Verify that the user has already received a copy of these 221 | materials or that you have already sent this user a copy. 222 | 223 | For an executable, the required form of the "work that uses the 224 | Library" must include any data and utility programs needed for 225 | reproducing the executable from it. However, as a special 226 | exception, the materials to be distributed need not include 227 | anything that is normally distributed (in either source or 228 | binary form) with the major components (compiler, kernel, and so 229 | on) of the operating system on which the executable runs, unless 230 | that component itself accompanies the executable. 231 | 232 | It may happen that this requirement contradicts the license 233 | restrictions of other proprietary libraries that do not normally 234 | accompany the operating system. Such a contradiction means you 235 | cannot use both them and the Library together in an executable 236 | that you distribute. 237 | 238 | 7. You may place library facilities that are a work based on the 239 | Library side-by-side in a single library together with other 240 | library facilities not covered by this License, and distribute such 241 | a combined library, provided that the separate distribution of the 242 | work based on the Library and of the other library facilities is 243 | otherwise permitted, and provided that you do these two things: 244 | 245 | 1. Accompany the combined library with a copy of the same 246 | work based on the Library, uncombined with any other library 247 | facilities. This must be distributed under the terms of the 248 | Sections above. 249 | 250 | 2. Give prominent notice with the combined library of the 251 | fact that part of it is a work based on the Library, and 252 | explaining where to find the accompanying uncombined form of 253 | the same work. 254 | 255 | 8. You may not copy, modify, sublicense, link with, or distribute 256 | the Library except as expressly provided under this License. Any 257 | attempt otherwise to copy, modify, sublicense, link with, or 258 | distribute the Library is void, and will automatically terminate 259 | your rights under this License. However, parties who have received 260 | copies, or rights, from you under this License will not have their 261 | licenses terminated so long as such parties remain in full 262 | compliance. 263 | 264 | 9. You are not required to accept this License, since you have not 265 | signed it. However, nothing else grants you permission to modify or 266 | distribute the Library or its derivative works. These actions are 267 | prohibited by law if you do not accept this License. Therefore, by 268 | modifying or distributing the Library (or any work based on the 269 | Library), you indicate your acceptance of this License to do so, 270 | and all its terms and conditions for copying, distributing or 271 | modifying the Library or works based on it. 272 | 273 | 10. Each time you redistribute the Library (or any work based on the 274 | Library), the recipient automatically receives a license from the 275 | original licensor to copy, distribute, link with or modify the 276 | Library subject to these terms and conditions. You may not impose 277 | any further restrictions on the recipients' exercise of the rights 278 | granted herein. You are not responsible for enforcing compliance by 279 | third parties with this License. 280 | 281 | 11. If, as a consequence of a court judgment or allegation of patent 282 | infringement or for any other reason (not limited to patent issues), 283 | conditions are imposed on you (whether by court order, agreement or 284 | otherwise) that contradict the conditions of this License, they do 285 | not excuse you from the conditions of this License. If you cannot 286 | distribute so as to satisfy simultaneously your obligations under 287 | this License and any other pertinent obligations, then as a 288 | consequence you may not distribute the Library at all. For example, 289 | if a patent license would not permit royalty-free redistribution of 290 | the Library by all those who receive copies directly or indirectly 291 | through you, then the only way you could satisfy both it and this 292 | License would be to refrain entirely from distribution of the 293 | Library. 294 | 295 | If any portion of this section is held invalid or unenforceable 296 | under any particular circumstance, the balance of the section is 297 | intended to apply, and the section as a whole is intended to 298 | apply in other circumstances. 299 | 300 | It is not the purpose of this section to induce you to infringe 301 | any patents or other property right claims or to contest 302 | validity of any such claims; this section has the sole purpose 303 | of protecting the integrity of the free software distribution 304 | system which is implemented by public license practices. Many 305 | people have made generous contributions to the wide range of 306 | software distributed through that system in reliance on 307 | consistent application of that system; it is up to the 308 | author/donor to decide if he or she is willing to distribute 309 | software through any other system and a licensee cannot impose 310 | that choice. 311 | 312 | This section is intended to make thoroughly clear what is 313 | believed to be a consequence of the rest of this License. 314 | 315 | 12. If the distribution and/or use of the Library is restricted in 316 | certain countries either by patents or by copyrighted interfaces, 317 | the original copyright holder who places the Library under this 318 | License may add an explicit geographical distribution limitation 319 | excluding those countries, so that distribution is permitted only in 320 | or among countries not thus excluded. In such case, this License 321 | incorporates the limitation as if written in the body of this 322 | License. 323 | 324 | 13. The Free Software Foundation may publish revised and/or new 325 | versions of the Lesser General Public License from time to 326 | time. Such new versions will be similar in spirit to the present 327 | version, but may differ in detail to address new problems or 328 | concerns. 329 | 330 | Each version is given a distinguishing version number. If the 331 | Library specifies a version number of this License which applies to 332 | it and "any later version", you have the option of following the 333 | terms and conditions either of that version or of any later version 334 | published by the Free Software Foundation. If the Library does not 335 | specify a license version number, you may choose any version ever 336 | published by the Free Software Foundation. 14. If you wish to 337 | incorporate parts of the Library into other free programs whose 338 | distribution conditions are incompatible with these, write to the 339 | author to ask for permission. For software which is copyrighted by 340 | the Free Software Foundation, write to the Free Software Foundation; 341 | we sometimes make exceptions for this. Our decision will be guided 342 | by the two goals of preserving the free status of all derivatives of 343 | our free software and of promoting the sharing and reuse of software 344 | generally. 345 | 346 | No Warranty 347 | 348 | 15. Because the library is licensed free of charge, there is no 349 | warranty for the library, to the extent permitted by applicable 350 | law. Except when otherwise stated in writing the copyright holders 351 | and/or other parties provide the library "as is" without warranty of 352 | any kind, either expressed or implied, including, but not limited 353 | to, the implied warranties of merchantability and fitness for a 354 | particular purpose. The entire risk as to the quality and 355 | performance of the library is with you. Should the library prove 356 | defective, you assume the cost of all necessary servicing, repair or 357 | correction. 358 | 359 | 16. In no event unless required by applicable law or agreed to in 360 | writing will any copyright holder, or any other party who may modify 361 | and/or redistribute the library as permitted above, be liable to you 362 | for damages, including any general, special, incidental or 363 | consequential damages arising out of the use or inability to use the 364 | library (including but not limited to loss of data or data being 365 | rendered inaccurate or losses sustained by you or third parties or a 366 | failure of the library to operate with any other software), even if 367 | such holder or other party has been advised of the possibility of 368 | such damages. 369 | 370 | -------------------------------------------------------------------------------- /site-lisp/nxml-mode/xmltok.el: -------------------------------------------------------------------------------- 1 | ;;; xmltok.el --- XML tokenization 2 | 3 | ;; Copyright (C) 2003, 2007-2012 Free Software Foundation, Inc. 4 | 5 | ;; Author: James Clark 6 | ;; Keywords: XML 7 | 8 | ;; This file is part of GNU Emacs. 9 | 10 | ;; GNU Emacs is free software: you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation, either version 3 of the License, or 13 | ;; (at your option) any later version. 14 | 15 | ;; GNU Emacs is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with GNU Emacs. If not, see . 22 | 23 | ;;; Commentary: 24 | 25 | ;; This implements an XML 1.0 parser. It also implements the XML 26 | ;; Namespaces Recommendation. It is designed to be conforming, but it 27 | ;; works a bit differently from a normal XML parser. An XML document 28 | ;; consists of the prolog and an instance. The prolog is parsed as a 29 | ;; single unit using `xmltok-forward-prolog'. The instance is 30 | ;; considered as a sequence of tokens, where a token is something like 31 | ;; a start-tag, a comment, a chunk of data or a CDATA section. The 32 | ;; tokenization of the instance is stateless: the tokenization of one 33 | ;; part of the instance does not depend on tokenization of the 34 | ;; preceding part of the instance. This allows the instance to be 35 | ;; parsed incrementally. The main entry point is `xmltok-forward': 36 | ;; this can be called at any point in the instance provided it is 37 | ;; between tokens. The other entry point is `xmltok-forward-special' 38 | ;; which skips over tokens other comments, processing instructions or 39 | ;; CDATA sections (i.e. the constructs in an instance that can contain 40 | ;; less than signs that don't start a token). 41 | ;; 42 | ;; This is a non-validating XML 1.0 processor. It does not resolve 43 | ;; parameter entities (including the external DTD subset) and it does 44 | ;; not resolve external general entities. 45 | ;; 46 | ;; It is non-conformant by design in the following respects. 47 | ;; 48 | ;; 1. It expects the client to detect aspects of well-formedness that 49 | ;; are not internal to a single token, specifically checking that 50 | ;; end-tags match start-tags and that the instance contains exactly 51 | ;; one element. 52 | ;; 53 | ;; 2. It expects the client to detect duplicate attributes. Detection 54 | ;; of duplicate attributes after expansion of namespace prefixes 55 | ;; requires the namespace processing state. Detection of duplicate 56 | ;; attributes before expansion of namespace prefixes does not, but is 57 | ;; redundant given that the client will do detection of duplicate 58 | ;; attributes after expansion of namespace prefixes. 59 | ;; 60 | ;; 3. It allows the client to recover from well-formedness errors. 61 | ;; This is essential for use in applications where the document is 62 | ;; being parsed during the editing process. 63 | ;; 64 | ;; 4. It does not support documents that do not conform to the lexical 65 | ;; requirements of the XML Namespaces Recommendation (e.g. a document 66 | ;; with a colon in an entity name). 67 | ;; 68 | ;; There are also a number of things that have not yet been 69 | ;; implemented that make it non-conformant. 70 | ;; 71 | ;; 1. It does not implement default attributes. ATTLIST declarations 72 | ;; are parsed, but no checking is done on the content of attribute 73 | ;; value literals specifying default attribute values, and default 74 | ;; attribute values are not reported to the client. 75 | ;; 76 | ;; 2. It does not implement internal entities containing elements. If 77 | ;; an internal entity is referenced and parsing its replacement text 78 | ;; yields one or more tags, then it will skip the reference and 79 | ;; report this to the client. 80 | ;; 81 | ;; 3. It does not check the syntax of public identifiers in the DTD. 82 | ;; 83 | ;; 4. It allows some non-ASCII characters in certain situations where 84 | ;; it should not. For example, it only enforces XML 1.0's 85 | ;; restrictions on name characters strictly for ASCII characters. The 86 | ;; problem here is XML's character model is based squarely on Unicode, 87 | ;; whereas Emacs's is not (as of version 21). It is not clear what 88 | ;; the right thing to do is. 89 | 90 | ;;; Code: 91 | 92 | (defvar xmltok-type nil) 93 | (defvar xmltok-start nil) 94 | (defvar xmltok-name-colon nil) 95 | (defvar xmltok-name-end nil) 96 | (defvar xmltok-replacement nil 97 | "String containing replacement for a character or entity reference.") 98 | 99 | (defvar xmltok-attributes nil 100 | "List containing attributes of last scanned element. 101 | Each member of the list is a vector representing an attribute, which 102 | can be accessed using the functions `xmltok-attribute-name-start', 103 | `xmltok-attribute-name-colon', `xmltok-attribute-name-end', 104 | `xmltok-attribute-value-start', `xmltok-attribute-value-end', 105 | `xmltok-attribute-raw-normalized-value', `xmltok-attribute-refs'.") 106 | 107 | (defvar xmltok-namespace-attributes nil 108 | "List containing namespace declarations of last scanned element. 109 | List has same format as `xmltok-attributes'.") 110 | 111 | (defvar xmltok-dtd nil 112 | "Information about the DTD used by `xmltok-forward'. 113 | `xmltok-forward-prolog' sets this up. 114 | 115 | It consists of an alist of general entity names vs definitions. The 116 | first member of the alist is t if references to entities not in the 117 | alist are well-formed \(e.g. because there's an external subset that 118 | wasn't parsed). 119 | 120 | Each general entity name is a string. The definition is either nil, 121 | a symbol, a string, a cons cell. If the definition is nil, then it 122 | means that it's an internal entity but the result of parsing it is 123 | unknown. If it is a symbol, then the symbol is either `unparsed', 124 | meaning the entity is an unparsed entity, `external', meaning the 125 | entity is or references an external entity, `element', meaning the 126 | entity includes one or more elements, or `not-well-formed', meaning 127 | the replacement text is not well-formed. If the definition is a 128 | string, then the replacement text of the entity is that string; this 129 | happens only during the parsing of the prolog. If the definition is 130 | a cons cell \(ER . AR), then ER specifies the string that results 131 | from referencing the entity in element content and AR is either nil, 132 | meaning the replacement text included a <, or a string which is the 133 | normalized attribute value.") 134 | 135 | (defvar xmltok-dependent-regions nil 136 | "List of descriptors of regions that a parsed token depends on. 137 | 138 | A token depends on a region if the region occurs after the token and a 139 | change in the region may require the token to be reparsed. This only 140 | happens with markup that is not well-formed. For example, if a , then the then the buffer must be reparsed from the space-count 0) 316 | (setq xmltok-type 'space)) 317 | (t 318 | (forward-char 1) 319 | (xmltok-scan-after-lt)))) 320 | ((eq ch ?\&) 321 | (cond ((> space-count 0) 322 | (setq xmltok-type 'space)) 323 | (t 324 | (forward-char 1) 325 | (xmltok-scan-after-amp 'xmltok-handle-entity)))) 326 | ((re-search-forward "[<&]\\|\\(]]>\\)" nil t) 327 | (cond ((not (match-beginning 1)) 328 | (goto-char (match-beginning 0)) 329 | ;; must have got a non-space char 330 | (setq xmltok-type 'data)) 331 | ((= (match-beginning 1) xmltok-start) 332 | (xmltok-add-error "Found `]]>' not closing a CDATA section") 333 | (setq xmltok-type 'not-well-formed)) 334 | (t 335 | (goto-char (match-beginning 0)) 336 | (setq xmltok-type 337 | (if (= (point) (+ xmltok-start space-count)) 338 | 'space 339 | 'data))))) 340 | ((eq ch nil) 341 | (setq xmltok-type 342 | (if (> space-count 0) 343 | 'space 344 | nil))) 345 | (t 346 | (goto-char (point-max)) 347 | (setq xmltok-type 'data))))) 348 | 349 | (defun xmltok-forward-special (bound) 350 | "Scan forward past the first special token starting at or after point. 351 | Return nil if there is no special token that starts before BOUND. 352 | CDATA sections, processing instructions and comments (and indeed 353 | anything starting with < following by ? or !) count as special. 354 | Return the type of the token." 355 | (when (re-search-forward "<[?!]" (1+ bound) t) 356 | (setq xmltok-start (match-beginning 0)) 357 | (goto-char (1+ xmltok-start)) 358 | (let ((case-fold-search nil)) 359 | (xmltok-scan-after-lt)))) 360 | 361 | (eval-when-compile 362 | 363 | ;; A symbolic regexp is represented by a list whose CAR is the string 364 | ;; containing the regexp and whose cdr is a list of symbolic names 365 | ;; for the groups in the string. 366 | 367 | ;; Construct a symbolic regexp from a regexp. 368 | (defun xmltok-r (str) 369 | (cons str nil)) 370 | 371 | ;; Concatenate zero of more regexps and symbolic regexps. 372 | (defun xmltok+ (&rest args) 373 | (let (strs names) 374 | (while args 375 | (let ((arg (car args))) 376 | (if (stringp arg) 377 | (setq strs (cons arg strs)) 378 | (setq strs (cons (car arg) strs)) 379 | (setq names (cons (cdr arg) names))) 380 | (setq args (cdr args)))) 381 | (cons (apply 'concat (nreverse strs)) 382 | (apply 'append (nreverse names)))))) 383 | 384 | (eval-when-compile 385 | ;; Make a symbolic group named NAME from the regexp R. 386 | ;; R may be a symbolic regexp or an ordinary regexp. 387 | (defmacro xmltok-g (name &rest r) 388 | (let ((sym (make-symbol "r"))) 389 | `(let ((,sym (xmltok+ ,@r))) 390 | (if (stringp ,sym) 391 | (cons (concat "\\(" ,sym "\\)") (cons ',name nil)) 392 | (cons (concat "\\(" (car ,sym) "\\)") (cons ',name (cdr ,sym))))))) 393 | 394 | (defun xmltok-p (&rest r) (xmltok+ "\\(?:" 395 | (apply 'xmltok+ r) 396 | "\\)")) 397 | 398 | ;; Get the group index of ELEM in a LIST of symbols. 399 | (defun xmltok-get-index (elem list) 400 | (or elem 401 | (error "Missing group name")) 402 | (let ((found nil) 403 | (i 1)) 404 | (while list 405 | (cond ((eq elem (car list)) 406 | (setq found i) 407 | (setq list nil)) 408 | (t 409 | (setq i (1+ i)) 410 | (setq list (cdr list))))) 411 | (or found 412 | (error "Bad group name %s" elem)))) 413 | 414 | ;; Define a macro SYM using a symbolic regexp R. 415 | ;; SYM can be called in three ways: 416 | ;; (SYM regexp) 417 | ;; expands to the regexp in R 418 | ;; (SYM start G) 419 | ;; expands to 420 | ;; (match-beginning N) 421 | ;; where N is the group index of G in R. 422 | ;; (SYM end G) 423 | ;; expands to 424 | ;; (match-end N) 425 | ;; where N is the group index of G in R. 426 | (defmacro xmltok-defregexp (sym r) 427 | `(defalias ',sym 428 | (let ((r ,r)) 429 | `(macro lambda (action &optional group-name) 430 | (cond ((eq action 'regexp) 431 | ,(car r)) 432 | ((or (eq action 'start) (eq action 'beginning)) 433 | (list 'match-beginning (xmltok-get-index group-name 434 | ',(cdr r)))) 435 | ((eq action 'end) 436 | (list 'match-end (xmltok-get-index group-name 437 | ',(cdr r)))) 438 | ((eq action 'string) 439 | (list 'match-string 440 | (xmltok-get-index group-name ',(cdr r)))) 441 | ((eq action 'string-no-properties) 442 | (list 'match-string-no-properties 443 | (xmltok-get-index group-name ',(cdr r)))) 444 | (t (error "Invalid action: %s" action)))))))) 445 | 446 | 447 | (eval-when-compile 448 | (let* ((or "\\|") 449 | (open "\\(?:") 450 | (gopen "\\(") 451 | (close "\\)") 452 | (name-start-char "[_[:alpha:]]") 453 | (name-continue-not-start-char "[-.[:digit:]]") 454 | (name-continue-char "[-._[:alnum:]]") 455 | (* "*") 456 | (+ "+") 457 | (opt "?") 458 | (question "\\?") 459 | (s "[ \r\t\n]") 460 | (s+ (concat s +)) 461 | (s* (concat s *)) 462 | (ncname (concat name-start-char name-continue-char *)) 463 | (entity-ref 464 | (xmltok+ (xmltok-g entity-name ncname) 465 | (xmltok-g entity-ref-close ";") opt)) 466 | (decimal-ref 467 | (xmltok+ (xmltok-g decimal "[0-9]" +) 468 | (xmltok-g decimal-ref-close ";") opt)) 469 | (hex-ref 470 | (xmltok+ "x" open 471 | (xmltok-g hex "[0-9a-fA-F]" +) 472 | (xmltok-g hex-ref-close ";") opt 473 | close opt)) 474 | (char-ref 475 | (xmltok+ (xmltok-g number-sign "#") 476 | open decimal-ref or hex-ref close opt)) 477 | (start-tag-close 478 | (xmltok+ open (xmltok-g start-tag-close s* ">") 479 | or open (xmltok-g empty-tag-slash s* "/") 480 | (xmltok-g empty-tag-close ">") opt close 481 | or (xmltok-g start-tag-s s+) 482 | close)) 483 | (start-tag 484 | (xmltok+ (xmltok-g start-tag-name 485 | ncname (xmltok-g start-tag-colon ":" ncname) opt) 486 | start-tag-close opt)) 487 | (end-tag 488 | (xmltok+ (xmltok-g end-tag-slash "/") 489 | open (xmltok-g end-tag-name 490 | ncname 491 | (xmltok-g end-tag-colon ":" ncname) opt) 492 | (xmltok-g end-tag-close s* ">") opt 493 | close opt)) 494 | (comment 495 | (xmltok+ (xmltok-g markup-declaration "!") 496 | (xmltok-g comment-first-dash "-" 497 | (xmltok-g comment-open "-") opt) opt)) 498 | (erb-section 499 | (xmltok+ "%" 500 | (xmltok-g erb-section-open "[^%]") opt)) 501 | (cdata-section 502 | (xmltok+ "!" 503 | (xmltok-g marked-section-open "\\[") 504 | open "C" 505 | open "D" 506 | open "A" 507 | open "T" 508 | open "A" 509 | (xmltok-g cdata-section-open "\\[" ) opt 510 | close opt ; A 511 | close opt ; T 512 | close opt ; A 513 | close opt ; D 514 | close opt)) ; C 515 | (processing-instruction 516 | (xmltok-g processing-instruction-question question))) 517 | 518 | (xmltok-defregexp xmltok-ncname (xmltok+ open ncname close)) 519 | 520 | (xmltok-defregexp xmltok-after-amp 521 | (xmltok+ entity-ref or char-ref)) 522 | (xmltok-defregexp xmltok-after-lt 523 | (xmltok+ start-tag 524 | or end-tag 525 | ;; cdata-section must come before comment 526 | ;; because we treat "))) 584 | (xmltok-defregexp 585 | xmltok-prolog 586 | (let* ((single-char (xmltok-g single-char "[[|,(\"'>]")) 587 | (internal-subset-close (xmltok-g internal-subset-close 588 | "][ \t\r\n]*>")) 589 | (starts-with-close-paren 590 | (xmltok-g close-paren 591 | ")" 592 | (xmltok-p 593 | (xmltok-g close-paren-occur "[+?]") 594 | or 595 | (xmltok-g close-paren-star "\\*")) 596 | opt)) 597 | (starts-with-percent 598 | (xmltok-g percent 599 | "%" (xmltok-g param-entity-ref 600 | ncname 601 | (xmltok-g param-entity-ref-close 602 | ";") opt) opt)) 603 | (starts-with-nmtoken-not-name 604 | (xmltok-g nmtoken 605 | (xmltok-p name-continue-not-start-char or ":") 606 | (xmltok-p name-continue-char or ":") *)) 607 | (nmtoken-after-colon 608 | (xmltok+ 609 | (xmltok-p name-continue-not-start-char or ":") 610 | (xmltok-p name-continue-char or ":") * 611 | or 612 | name-start-char 613 | name-continue-char * 614 | ":" 615 | (xmltok-p name-continue-char or ":") *)) 616 | (after-ncname 617 | (xmltok+ (xmltok-g ncname-nmtoken 618 | ":" (xmltok-p nmtoken-after-colon)) 619 | or (xmltok-p (xmltok-g colon ":" ncname) 620 | (xmltok-g colon-name-occur "[?+*]") opt) 621 | or (xmltok-g ncname-occur "[?+*]") 622 | or (xmltok-g ncname-colon ":"))) 623 | (starts-with-name 624 | (xmltok-g name ncname (xmltok-p after-ncname) opt)) 625 | (starts-with-hash 626 | (xmltok-g pound 627 | "#" (xmltok-g hash-name ncname))) 628 | (markup-declaration 629 | (xmltok-g markup-declaration 630 | "!" (xmltok-p (xmltok-g comment-first-dash "-" 631 | (xmltok-g comment-open "-") opt) 632 | or (xmltok-g named-markup-declaration 633 | ncname)) opt)) 634 | (after-lt 635 | (xmltok+ markup-declaration 636 | or (xmltok-g processing-instruction-question 637 | question) 638 | or (xmltok-g instance-start 639 | ncname))) 640 | (starts-with-lt (xmltok-g less-than "<" (xmltok-p after-lt) opt))) 641 | (xmltok+ starts-with-lt 642 | or single-char 643 | or starts-with-close-paren 644 | or starts-with-percent 645 | or starts-with-name 646 | or starts-with-nmtoken-not-name 647 | or starts-with-hash 648 | or internal-subset-close))))) 649 | 650 | (defconst xmltok-ncname-regexp (xmltok-ncname regexp)) 651 | 652 | (defun xmltok-scan-after-lt () 653 | (cond ((not (looking-at (xmltok-after-lt regexp))) 654 | (xmltok-add-error "`<' that is not markup must be entered as `<'") 655 | (setq xmltok-type 'not-well-formed)) 656 | (t 657 | (goto-char (match-end 0)) 658 | (cond ((xmltok-after-lt start start-tag-close) 659 | (setq xmltok-name-end 660 | (xmltok-after-lt end start-tag-name)) 661 | (setq xmltok-name-colon 662 | (xmltok-after-lt start start-tag-colon)) 663 | (setq xmltok-attributes nil) 664 | (setq xmltok-namespace-attributes nil) 665 | (setq xmltok-type 'start-tag)) 666 | ((xmltok-after-lt start end-tag-close) 667 | (setq xmltok-name-end 668 | (xmltok-after-lt end end-tag-name)) 669 | (setq xmltok-name-colon 670 | (xmltok-after-lt start end-tag-colon)) 671 | (setq xmltok-type 'end-tag)) 672 | ((xmltok-after-lt start start-tag-s) 673 | (setq xmltok-name-end 674 | (xmltok-after-lt end start-tag-name)) 675 | (setq xmltok-name-colon 676 | (xmltok-after-lt start start-tag-colon)) 677 | (setq xmltok-namespace-attributes nil) 678 | (setq xmltok-attributes nil) 679 | (xmltok-scan-attributes) 680 | xmltok-type) 681 | ((xmltok-after-lt start empty-tag-close) 682 | (setq xmltok-name-end 683 | (xmltok-after-lt end start-tag-name)) 684 | (setq xmltok-name-colon 685 | (xmltok-after-lt start start-tag-colon)) 686 | (setq xmltok-attributes nil) 687 | (setq xmltok-namespace-attributes nil) 688 | (setq xmltok-type 'empty-element)) 689 | ((xmltok-after-lt start cdata-section-open) 690 | (setq xmltok-type 691 | (if (search-forward "]]>" nil t) 692 | 'cdata-section 693 | (xmltok-add-error "No closing ]]>") 694 | (xmltok-add-dependent 'xmltok-unclosed-reparse-p 695 | nil 696 | nil 697 | "]]>") 698 | 'not-well-formed))) 699 | ((xmltok-after-lt start erb-section-open) 700 | (setq xmltok-type 701 | (if (re-search-forward "[^%]%>" nil t) 702 | 'erb-section 703 | (xmltok-add-error "No closing %>") 704 | (xmltok-add-dependent 'xmltok-unclosed-reparse-p 705 | nil 706 | nil 707 | "%>") 708 | 'not-well-formed))) 709 | ((xmltok-after-lt start processing-instruction-question) 710 | (xmltok-scan-after-processing-instruction-open)) 711 | ((xmltok-after-lt start comment-open) 712 | (xmltok-scan-after-comment-open)) 713 | ((xmltok-after-lt start empty-tag-slash) 714 | (setq xmltok-name-end 715 | (xmltok-after-lt end start-tag-name)) 716 | (setq xmltok-name-colon 717 | (xmltok-after-lt start start-tag-colon)) 718 | (setq xmltok-attributes nil) 719 | (setq xmltok-namespace-attributes nil) 720 | (xmltok-add-error "Expected `/>'" (1- (point))) 721 | (setq xmltok-type 'partial-empty-element)) 722 | ((xmltok-after-lt start start-tag-name) 723 | (xmltok-add-error "Missing `>'" 724 | nil 725 | (1+ xmltok-start)) 726 | (setq xmltok-name-end 727 | (xmltok-after-lt end start-tag-name)) 728 | (setq xmltok-name-colon 729 | (xmltok-after-lt start start-tag-colon)) 730 | (setq xmltok-namespace-attributes nil) 731 | (setq xmltok-attributes nil) 732 | (setq xmltok-type 'partial-start-tag)) 733 | ((xmltok-after-lt start end-tag-name) 734 | (setq xmltok-name-end (xmltok-after-lt end end-tag-name)) 735 | (setq xmltok-name-colon 736 | (xmltok-after-lt start end-tag-colon)) 737 | (cond ((and (not xmltok-name-colon) 738 | (eq (char-after) ?:)) 739 | (goto-char (1+ (point))) 740 | (xmltok-add-error "Expected name following `:'" 741 | (1- (point)))) 742 | (t 743 | (xmltok-add-error "Missing `>'" 744 | nil 745 | (1+ xmltok-start)))) 746 | (setq xmltok-type 'partial-end-tag)) 747 | ((xmltok-after-lt start end-tag-slash) 748 | (xmltok-add-error "Expected name following `) in unclosed PI 774 | (defun xmltok-scan-after-processing-instruction-open () 775 | (cond ((not (search-forward "?>" nil t)) 776 | (xmltok-add-error "No closing ?>" 777 | xmltok-start 778 | (+ xmltok-start 2)) 779 | (xmltok-add-dependent 'xmltok-unclosed-reparse-p 780 | nil 781 | nil 782 | "?>") 783 | (setq xmltok-type 'not-well-formed)) 784 | (t 785 | (cond ((not (save-excursion 786 | (goto-char (+ 2 xmltok-start)) 787 | (and (looking-at (xmltok-ncname regexp)) 788 | (setq xmltok-name-end (match-end 0))))) 789 | (setq xmltok-name-end (+ xmltok-start 2)) 790 | (xmltok-add-error "") 813 | (xmltok-add-dependent 'xmltok-unclosed-reparse-p 814 | nil 815 | nil 816 | ;; not --> because 817 | ;; -- is not allowed 818 | ;; in comments in XML 819 | "--") 820 | 'not-well-formed) 821 | ((eq (char-after) ?>) 822 | (goto-char (1+ (point))) 823 | 'comment) 824 | (t 825 | (xmltok-add-dependent 826 | 'xmltok-semi-closed-reparse-p 827 | nil 828 | (point) 829 | "--" 830 | 2) 831 | ;; just include the