[from now] 2013/09/05 11:50:40

diff --git a/.bashrc b/.bashrc
index d6a9630..2bba9cc 100644
--- a/.bashrc
+++ b/.bashrc
@@ -7,10 +7,6 @@ PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting
 # emacs23.4
 alias emacs='/usr/local/Cellar/emacs/23.4/Emacs.app/Contents/MacOS/Emacs -nw'

-# rmtrash
-alias rm='rmtrash'
-alias mv='mv -i'
-
 # ag
 # http://qiita.com/yuyuchu3333/items/4c57186e37db9eb3db15
 alias ag='ag --smart-case --color --stats' # --pager "less -F"'
diff --git a/.emacs.d/ac-comphist.dat b/.emacs.d/ac-comphist.dat
index 259280d..60016ca 100644
--- a/.emacs.d/ac-comphist.dat
+++ b/.emacs.d/ac-comphist.dat
@@ -1,12 +1,12 @@
-((("Line</key>" .
-   [1 0 0 0 0 0 0 0 0 0])
-  ("<dict>" .
-   [1 0 0 0 0 0])
-  ("term" .
-   [1 0 0 0])
-  ("each" .
+((("line" .
    [1 0 0 0])
   ("split" .
    [1 0 0 0 0])
-  ("line" .
-   [1 0 0 0])))
+  ("each" .
+   [1 0 0 0])
+  ("term" .
+   [1 0 0 0])
+  ("<dict>" .
+   [1 0 0 0 0 0])
+  ("Line</key>" .
+   [1 0 0 0 0 0 0 0 0 0])))
diff --git a/.emacs.d/elpa/magit-1.2.0/dir b/.emacs.d/elpa/magit-1.2.0/dir
new file mode 100644
index 0000000..2e646db
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Magit: (magit).        Using Git from Emacs with Magit.
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-autoloads.el b/.emacs.d/elpa/magit-1.2.0/magit-autoloads.el
new file mode 100644
index 0000000..fad5f83
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-autoloads.el
@@ -0,0 +1,160 @@
+;;; magit-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+
+;;;### (autoloads (magit-status) "magit" "magit.el" (20987 24403))
+;;; Generated autoloads from magit.el
+
+(autoload 'magit-status "magit" "\
+Open a Magit status buffer for the Git repository containing
+DIR.  If DIR is not within a Git repository, offer to create a
+Git repository in DIR.
+
+Interactively, a prefix argument means to ask the user which Git
+repository to use even if `default-directory' is under Git control.
+Two prefix arguments means to ignore `magit-repo-dirs' when asking for
+user input.
+
+\(fn DIR)" t nil)
+
+;;;***
+
+;;;### (autoloads (magit-blame-mode) "magit-blame" "magit-blame.el"
+;;;;;;  (20987 24403))
+;;; Generated autoloads from magit-blame.el
+
+(autoload 'magit-blame-mode "magit-blame" "\
+Display blame information inline.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (turn-on-magit-stgit magit-stgit-mode) "magit-stgit"
+;;;;;;  "magit-stgit.el" (20987 24403))
+;;; Generated autoloads from magit-stgit.el
+
+(autoload 'magit-stgit-mode "magit-stgit" "\
+StGit support for Magit
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-magit-stgit "magit-stgit" "\
+Unconditionally turn on `magit-stgit-mode'.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (turn-on-magit-svn magit-svn-mode) "magit-svn"
+;;;;;;  "magit-svn.el" (20987 24403))
+;;; Generated autoloads from magit-svn.el
+
+(autoload 'magit-svn-mode "magit-svn" "\
+SVN support for Magit
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-magit-svn "magit-svn" "\
+Unconditionally turn on `magit-svn-mode'.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (turn-on-magit-topgit magit-topgit-mode) "magit-topgit"
+;;;;;;  "magit-topgit.el" (20987 24403))
+;;; Generated autoloads from magit-topgit.el
+
+(autoload 'magit-topgit-mode "magit-topgit" "\
+Topgit support for Magit
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-magit-topgit "magit-topgit" "\
+Unconditionally turn on `magit-topgit-mode'.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (global-magit-wip-save-mode magit-wip-save-mode
+;;;;;;  magit-wip-mode) "magit-wip" "magit-wip.el" (20987 24403))
+;;; Generated autoloads from magit-wip.el
+
+(defvar magit-wip-mode nil "\
+Non-nil if Magit-Wip mode is enabled.
+See the command `magit-wip-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `magit-wip-mode'.")
+
+(custom-autoload 'magit-wip-mode "magit-wip" nil)
+
+(autoload 'magit-wip-mode "magit-wip" "\
+In Magit log buffers; give wip refs a special appearance.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'magit-wip-save-mode "magit-wip" "\
+Magit support for committing to a work-in-progress ref.
+
+When this minor mode is turned on and a file is saved inside a writable
+git repository then it is also committed to a special work-in-progress
+ref.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-magit-wip-save-mode nil "\
+Non-nil if Global-Magit-Wip-Save mode is enabled.
+See the command `global-magit-wip-save-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-magit-wip-save-mode'.")
+
+(custom-autoload 'global-magit-wip-save-mode "magit-wip" nil)
+
+(autoload 'global-magit-wip-save-mode "magit-wip" "\
+Toggle Magit-Wip-Save mode in every possible buffer.
+With prefix ARG, turn Global-Magit-Wip-Save mode on if and only if
+ARG is positive.
+Magit-Wip-Save mode is enabled in all buffers where
+`turn-on-magit-wip-save' would do it.
+See `magit-wip-save-mode' for more information on Magit-Wip-Save mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (rebase-mode) "rebase-mode" "rebase-mode.el" (20987
+;;;;;;  24403))
+;;; Generated autoloads from rebase-mode.el
+
+(autoload 'rebase-mode "rebase-mode" "\
+Major mode for editing of a Git rebase file.
+
+Rebase files are generated when you run 'git rebase -i' or run
+`magit-interactive-rebase'.  They describe how Git should perform
+the rebase.  See the documentation for git-rebase (e.g., by
+running 'man git-rebase' at the command line) for details.
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("git-rebase-todo" . rebase-mode))
+
+;;;***
+
+;;;### (autoloads nil nil ("magit-bisect.el" "magit-key-mode.el"
+;;;;;;  "magit-pkg.el") (20987 24403 543116))
+
+;;;***
+
+(provide 'magit-autoloads)
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; magit-autoloads.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-bisect.el b/.emacs.d/elpa/magit-1.2.0/magit-bisect.el
new file mode 100644
index 0000000..cdb6455
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-bisect.el
@@ -0,0 +1,195 @@
+(require 'magit)
+
+(defvar magit--bisect-last-pos)
+(defvar magit--bisect-tmp-file)
+(defvar magit--bisect-info nil)
+(make-variable-buffer-local 'magit--bisect-info)
+(put 'magit--bisect-info 'permanent-local t)
+
+(defun magit--bisecting-p (&optional required-status)
+  "Return t if a bisect session is running.
+If REQUIRED-STATUS is not nil then the current status must also
+match REQUIRED-STATUS."
+  (and (file-exists-p (concat (magit-git-dir) "BISECT_LOG"))
+       (or (not required-status)
+           (eq (plist-get (magit--bisect-info) :status)
+               required-status))))
+
+(defun magit--bisect-info ()
+  (with-current-buffer (magit-find-status-buffer)
+    (or (if (local-variable-p 'magit--bisect-info) magit--bisect-info)
+        (list :status (if (magit--bisecting-p) 'running 'not-running)))))
+
+(defun magit--bisect-cmd (&rest args)
+  "Run `git bisect ...' and update the status buffer"
+  (with-current-buffer (magit-find-status-buffer)
+    (let* ((output (apply 'magit-git-lines (append '("bisect") args)))
+           (cmd (car args))
+           (first-line (car output)))
+      (save-match-data
+        (setq magit--bisect-info
+              (cond ((string= cmd "reset")
+                     (list :status 'not-running))
+                    ;; Bisecting: 78 revisions left to test after this (roughly 6 steps)
+                    ((string-match "^Bisecting:\\s-+\\([0-9]+\\).+roughly\\s-+\\([0-9]+\\)" first-line)
+                     (list :status 'running
+                           :revs (match-string 1 first-line)
+                           :steps (match-string 2 first-line)))
+                    ;; e2596955d9253a80aec9071c18079705597fa102 is the first bad commit
+                    ((string-match "^\\([a-f0-9]+\\)\\s-.*first bad commit" first-line)
+                     (list :status 'finished
+                           :bad (match-string 1 first-line)))
+                    (t
+                     (list :status 'error)))))))
+  (magit-refresh))
+
+(defun magit--bisect-info-for-status (branch)
+  "Return bisect info suitable for display in the status buffer"
+  (let* ((info (magit--bisect-info))
+         (status (plist-get info :status)))
+    (cond ((eq status 'not-running)
+           (or branch "(detached)"))
+          ((eq status 'running)
+           (format "(bisecting; %s revisions & %s steps left)"
+                   (or (plist-get info :revs) "unknown number of")
+                   (or (plist-get info :steps) "unknown number of")))
+          ((eq status 'finished)
+           (format "(bisected: first bad revision is %s)" (plist-get info :bad)))
+          (t
+           "(bisecting; unknown error occured)"))))
+
+(defun magit-bisect-start ()
+  "Start a bisect session"
+  (interactive)
+  (if (magit--bisecting-p)
+      (error "Already bisecting"))
+  (let ((bad (magit-read-rev "Start bisect with known bad revision" "HEAD"))
+        (good (magit-read-rev "Good revision" (magit-default-rev))))
+    (magit--bisect-cmd "start" bad good)))
+
+(defun magit-bisect-reset ()
+  "Quit a bisect session"
+  (interactive)
+  (unless (magit--bisecting-p)
+    (error "Not bisecting"))
+  (magit--bisect-cmd "reset"))
+
+(defun magit-bisect-good ()
+  "Tell git that the current revision is good during a bisect session"
+  (interactive)
+  (unless (magit--bisecting-p 'running)
+    (error "Not bisecting"))
+  (magit--bisect-cmd "good"))
+
+(defun magit-bisect-bad ()
+  "Tell git that the current revision is bad during a bisect session"
+  (interactive)
+  (unless (magit--bisecting-p 'running)
+    (error "Not bisecting"))
+  (magit--bisect-cmd "bad"))
+
+(defun magit-bisect-skip ()
+  "Tell git to skip the current revision during a bisect session."
+  (interactive)
+  (unless (magit--bisecting-p 'running)
+    (error "Not bisecting"))
+  (magit--bisect-cmd "skip"))
+
+(defun magit-bisect-log ()
+  "Show the bisect log"
+  (interactive)
+  (unless (magit--bisecting-p)
+    (error "Not bisecting"))
+  (magit-run-git "bisect" "log")
+  (magit-display-process))
+
+(defun magit-bisect-visualize ()
+  "Show the remaining suspects with gitk"
+  (interactive)
+  (unless (magit--bisecting-p)
+    (error "Not bisecting"))
+  (magit-run-git "bisect" "visualize")
+  (unless (getenv "DISPLAY")
+    (magit-display-process)))
+
+(easy-mmode-defmap magit-bisect-minibuffer-local-map
+  '(("\C-i" . comint-dynamic-complete-filename))
+  "Keymap for minibuffer prompting of rebase command."
+  :inherit minibuffer-local-map)
+
+(defvar magit-bisect-mode-history nil
+  "Previously run bisect commands.")
+
+(defun magit-bisect-run (command)
+  "Bisect automatically by running commands after each step"
+  (interactive
+   (list
+    (read-from-minibuffer "Run command (like this): "
+                          ""
+                          magit-bisect-minibuffer-local-map
+                          nil
+                          'magit-bisect-mode-history)))
+  (unless (magit--bisecting-p)
+    (error "Not bisecting"))
+  (let ((file (make-temp-file "magit-bisect-run"))
+        buffer)
+    (with-temp-buffer
+      (insert "#!/bin/sh\n" command "\n")
+      (write-region (point-min) (point-max) file))
+    (set-file-modes file #o755)
+    (magit-run-git-async "bisect" "run" file)
+    (magit-display-process)
+    (setq buffer (get-buffer magit-process-buffer-name))
+    (with-current-buffer buffer
+      (set (make-local-variable 'magit--bisect-last-pos) 0)
+      (set (make-local-variable 'magit--bisect-tmp-file) file))
+    (set-process-filter (get-buffer-process buffer) 'magit--bisect-run-filter)
+    (set-process-sentinel (get-buffer-process buffer) 'magit--bisect-run-sentinel)))
+
+(defun magit--bisect-run-filter (process output)
+  (with-current-buffer (process-buffer process)
+    (save-match-data
+      (let ((inhibit-read-only t)
+            line new-info)
+        (insert output)
+        (goto-char magit--bisect-last-pos)
+        (beginning-of-line)
+        (while (< (point) (point-max))
+          (cond ( ;; Bisecting: 78 revisions left to test after this (roughly 6 steps)
+                 (looking-at "^Bisecting:\\s-+\\([0-9]+\\).+roughly\\s-+\\([0-9]+\\)")
+                 (setq new-info (list :status 'running
+                                      :revs (match-string 1)
+                                      :steps (match-string 2))))
+                ( ;; e2596955d9253a80aec9071c18079705597fa102 is the first bad commit
+                 (looking-at "^\\([a-f0-9]+\\)\\s-.*first bad commit")
+                 (setq new-info (list :status 'finished
+                                      :bad (match-string 1)))))
+          (forward-line 1))
+        (goto-char (point-max))
+        (setq magit--bisect-last-pos (point))
+        (if new-info
+            (with-current-buffer (magit-find-status-buffer)
+              (setq magit--bisect-info new-info)
+              (magit--bisect-update-status-buffer)))))))
+
+(defun magit--bisect-run-sentinel (process event)
+  (if (string-match-p "^finish" event)
+      (with-current-buffer (process-buffer process)
+        (delete-file magit--bisect-tmp-file)))
+  (magit-process-sentinel process event))
+
+(defun magit--bisect-update-status-buffer ()
+  (with-current-buffer (magit-find-status-buffer)
+    (save-excursion
+      (save-match-data
+        (let ((inhibit-read-only t))
+          (goto-char (point-min))
+          (when (search-forward-regexp "Local:" nil t)
+            (beginning-of-line)
+            (kill-line)
+            (insert (format "Local:    %s %s"
+                            (propertize (magit--bisect-info-for-status (magit-get-current-branch))
+                                        'face 'magit-branch)
+                            (abbreviate-file-name default-directory)))))))))
+
+(provide 'magit-bisect)
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-bisect.elc b/.emacs.d/elpa/magit-1.2.0/magit-bisect.elc
new file mode 100644
index 0000000..0eb3181
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-bisect.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-blame.el b/.emacs.d/elpa/magit-1.2.0/magit-blame.el
new file mode 100644
index 0000000..8518dcb
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-blame.el
@@ -0,0 +1,303 @@
+;;; magit-blame.el --- blame support for magit
+
+;; Copyright (C) 2012  Rüdiger Sonderfeld
+;; Copyright (C) 2012  Yann Hodique
+;; Copyright (C) 2011  byplayer
+;; Copyright (C) 2010  Alexander Prusov
+;; Copyright (C) 2009  Tim Moore
+;; Copyright (C) 2008  Linh Dang
+;; Copyright (C) 2008  Marius Vollmer
+
+;; Author: Yann Hodique <yann.hodique@gmail.com>
+;; Keywords:
+
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This code has been backported from Egg (Magit fork) to Magit
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'magit)
+
+(defface magit-blame-header
+  '((t :inherit magit-header))
+  "Face for blame header."
+  :group 'magit-faces)
+
+(defface magit-blame-sha1
+  '((t :inherit (magit-log-sha1
+                 magit-blame-header)))
+  "Face for blame sha1."
+  :group 'magit-faces)
+
+(defface magit-blame-culprit
+  '((t :inherit magit-blame-header))
+  "Face for blame culprit."
+  :group 'magit-faces)
+
+(defface magit-blame-time
+  '((t :inherit magit-blame-header))
+  "Face for blame time."
+  :group 'magit-faces)
+
+(defface magit-blame-subject
+  '((t :inherit (magit-log-message magit-blame-header)))
+  "Face for blame tag line."
+  :group 'magit-faces)
+
+(defconst magit-blame-map
+  (let ((map (make-sparse-keymap "Magit:Blame")))
+    (define-key map (kbd "l") 'magit-blame-locate-commit)
+    (define-key map (kbd "RET") 'magit-blame-locate-commit)
+    (define-key map (kbd "q") 'magit-blame-mode)
+    (define-key map (kbd "n") 'magit-blame-next-chunk)
+    (define-key map (kbd "p") 'magit-blame-previous-chunk)
+    map)
+  "Keymap for an annotated section.\\{magit-blame-map}")
+
+(defvar magit-blame-buffer-read-only)
+(make-variable-buffer-local 'magit-blame-buffer-read-only)
+
+;;;###autoload
+(define-minor-mode magit-blame-mode
+  "Display blame information inline."
+  :keymap magit-blame-map
+  :lighter " blame"
+  (unless (buffer-file-name)
+    (error "Current buffer has no associated file!"))
+  (when (and (buffer-modified-p)
+             (y-or-n-p (format "save %s first? " (buffer-file-name))))
+    (save-buffer))
+
+  (if magit-blame-mode
+      (progn
+        (setq magit-blame-buffer-read-only buffer-read-only)
+        (magit-blame-file-on (current-buffer))
+        (set-buffer-modified-p nil)
+        (setq buffer-read-only t))
+    (magit-blame-file-off (current-buffer))
+    (set-buffer-modified-p nil)
+    (setq buffer-read-only magit-blame-buffer-read-only)))
+
+(defun magit-blame-file-off (buffer)
+  (save-excursion
+    (save-restriction
+      (with-current-buffer buffer
+        (widen)
+        (mapc (lambda (ov)
+                (if (overlay-get ov :blame)
+                    (delete-overlay ov)))
+              (overlays-in (point-min) (point-max)))))))
+
+(defun magit-blame-file-on (buffer)
+  (magit-blame-file-off buffer)
+  (save-excursion
+    (with-current-buffer buffer
+      (save-restriction
+        (with-temp-buffer
+          (magit-git-insert (list "blame" "--porcelain" "--"
+                                  (file-name-nondirectory
+                                   (buffer-file-name buffer))))
+          (magit-blame-parse buffer (current-buffer)))))))
+
+(defun magit-blame-locate-commit (pos)
+  "Jump to a commit in the branch history from an annotated blame section."
+  (interactive "d")
+  (let ((overlays (overlays-at pos))
+        sha1)
+    (dolist (ov overlays)
+      (if (overlay-get ov :blame)
+          (setq sha1 (plist-get (nth 3 (overlay-get ov :blame)) :sha1))))
+    (if sha1
+        (magit-show-commit sha1))))
+
+(defun magit-find-next-overlay-change (BEG END PROP)
+  "Return the next position after BEG where an overlay matching a
+property PROP starts or ends. If there are no matching overlay
+boundaries from BEG to END, the return value is nil."
+  (save-excursion
+    (goto-char BEG)
+    (catch 'found
+      (flet ((overlay-change (pos)
+                             (if (< BEG END) (next-overlay-change pos)
+                               (previous-overlay-change pos)))
+             (within-bounds-p (pos)
+                              (if (< BEG END) (< pos END)
+                                (> pos END))))
+        (let ((ov-pos BEG))
+          ;; iterate through overlay changes from BEG to END
+          (while (within-bounds-p ov-pos)
+            (let* ((next-ov-pos (overlay-change ov-pos))
+                   ;; search for an overlay with a PROP property
+                   (next-ov
+                    (let ((overlays (overlays-at next-ov-pos)))
+                      (while (and overlays
+                                  (not (overlay-get (car overlays) PROP)))
+                        (setq overlays (cdr overlays)))
+                      (car overlays))))
+              (if next-ov
+                  ;; found the next overlay with prop PROP at next-ov-pos
+                  (throw 'found next-ov-pos)
+                ;; no matching overlay found, keep looking
+                (setq ov-pos next-ov-pos)))))))))
+
+(defun magit-blame-next-chunk (pos)
+  "Go to the next blame chunk."
+  (interactive "d")
+  (let ((next-chunk-pos (magit-find-next-overlay-change pos (point-max) :blame)))
+    (when next-chunk-pos
+      (goto-char next-chunk-pos))))
+
+(defun magit-blame-previous-chunk (pos)
+  "Go to the previous blame chunk."
+  (interactive "d")
+  (let ((prev-chunk-pos (magit-find-next-overlay-change pos (point-min) :blame)))
+    (when prev-chunk-pos
+      (goto-char prev-chunk-pos))))
+
+(defcustom magit-time-format-string "%Y-%m-%dT%T%z"
+  "How to format time in magit-blame header."
+  :group 'magit
+  :type 'string)
+
+(defun magit-blame-decode-time (unixtime &optional tz)
+  "Decode UNIXTIME into (HIGH LOW) format.
+
+The second argument TZ can be used to add the timezone in (-)HHMM
+format to UNIXTIME.  UNIXTIME should be either a number
+containing seconds since epoch or Emacs's (HIGH LOW
+. IGNORED) format."
+  (when (numberp tz)
+    (unless (numberp unixtime)
+      (setq unixtime (float-time unixtime)))
+    (let* ((ptz (abs tz))
+           (min (+ (* (/ ptz 100) 60)
+                   (mod ptz 100))))
+      (setq unixtime (+ (* (if (< tz 0) (- min) min) 60) unixtime))))
+
+  (when (numberp unixtime)
+    (setq unixtime (seconds-to-time unixtime)))
+  unixtime)
+
+(defun magit-blame-format-time-string (format &optional unixtime tz)
+  "Use FORMAT to format the time UNIXTIME, or now if omitted.
+
+UNIXTIME is specified as a number containing seconds since epoch
+or Emacs's (HIGH LOW . IGNORED) format.  The optional argument TZ
+can be used to set the time zone.  If TZ is a number it is
+treated as a (-)HHMM offset to Universal Time.  If TZ is not
+a number and non-nil the time is printed in UTC.  If TZ is nil
+the local zime zone is used.  The format of the function is
+similar to `format-time-string' except for %Z which is not
+officially supported at the moment."
+  (unless unixtime
+    (setq unixtime (current-time)))
+  (when (numberp tz) ;; TODO add support for %Z
+    (setq format (replace-regexp-in-string "%z" (format "%+05d" tz) format)))
+  (format-time-string format (magit-blame-decode-time unixtime tz) tz))
+
+(defun magit-blame-parse (target-buf blame-buf)
+  "Parse blame-info in buffer BLAME-BUF and decorate TARGET-BUF buffer."
+  (save-match-data
+    (let ((blank (propertize " " 'face 'magit-blame-header))
+          (nl (propertize "\n" 'face 'magit-blame-header))
+          (commit-hash (make-hash-table :test 'equal :size 577))
+          commit commit-info old-line new-line num old-file subject author
+          author-time author-timezone info ov beg end blame)
+      (with-current-buffer blame-buf
+        (goto-char (point-min))
+        ;; search for a ful commit info
+        (while (re-search-forward "^\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)$" nil t)
+          (setq commit (match-string-no-properties 1)
+                old-line (string-to-number
+                          (match-string-no-properties 2))
+                new-line (string-to-number
+                          (match-string-no-properties 3))
+                num (string-to-number
+                     (match-string-no-properties 4)))
+          ;; was this commit already seen (and stored in the hash)?
+          (setq commit-info (gethash commit commit-hash))
+          ;; Nope, this is the 1st time, the full commit-info follow.
+          (unless commit-info
+            (re-search-forward "^author \\(.+\\)$")
+            (setq author (match-string-no-properties 1))
+            (re-search-forward "^author-time \\(.+\\)$")
+            (setq author-time (string-to-number
+                               (match-string-no-properties 1)))
+            (re-search-forward "^author-tz \\(.+\\)$")
+            (setq author-timezone (string-to-number
+                                   (match-string-no-properties 1)))
+            (re-search-forward "^summary \\(.+\\)$")
+            (setq subject (match-string-no-properties 1))
+            (re-search-forward "^filename \\(.+\\)$")
+            (setq old-file (match-string-no-properties 1))
+            (setq commit-info (list :sha1 commit :author author
+                                    :author-time author-time
+                                    :author-timezone author-timezone
+                                    :subject subject :file old-file))
+            ;; save it in the hash
+            (puthash commit commit-info commit-hash))
+          ;; add the current blame-block into the list INFO.
+          (setq info (cons (list old-line new-line num commit-info)
+                           info))))
+      ;; now do from beginning
+      (setq info (nreverse info))
+      (with-current-buffer target-buf
+        ;; for every blame chunk
+        (dolist (chunk info)
+          (setq commit-info (nth 3 chunk)
+                old-line (nth 0 chunk)
+                new-line (nth 1 chunk)
+                num (nth 2 chunk)
+                commit (plist-get commit-info :sha1)
+                author (plist-get commit-info :author)
+                author-time (plist-get commit-info :author-time)
+                author-timezone (plist-get commit-info :author-timezone)
+                subject (plist-get commit-info :subject))
+
+          (goto-char (point-min))
+          (forward-line (1- new-line))
+
+          (setq beg (line-beginning-position)
+                end (save-excursion
+                      (forward-line num)
+                      (line-beginning-position)))
+          ;; mark the blame chunk
+          (put-text-property beg end :blame chunk)
+
+          ;; make an overlay with blame info as 'before-string
+          ;; on the current chunk.
+          (setq ov (make-overlay beg end))
+          (overlay-put ov :blame chunk)
+          (setq blame (concat
+                       (propertize (substring-no-properties commit 0 8)
+                                   'face 'magit-blame-sha1)
+                       blank
+                       (propertize (format "%-20s" author)
+                                   'face 'magit-blame-culprit)
+                       blank
+                       (propertize (magit-blame-format-time-string
+                                    magit-time-format-string
+                                    author-time author-timezone)
+                                   'face 'magit-blame-time)
+                       blank
+                       (propertize subject 'face 'magit-blame-subject)
+                       blank nl))
+          (overlay-put ov 'before-string blame))))))
+
+(provide 'magit-blame)
+;;; magit-blame.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-blame.elc b/.emacs.d/elpa/magit-1.2.0/magit-blame.elc
new file mode 100644
index 0000000..1bc4d2f
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-blame.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-key-mode.el b/.emacs.d/elpa/magit-1.2.0/magit-key-mode.el
new file mode 100644
index 0000000..2fcf296
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-key-mode.el
@@ -0,0 +1,521 @@
+(require 'magit)
+
+(eval-when-compile (require 'cl))
+
+(defvar magit-key-mode-key-maps '()
+  "This will be filled lazily with proper `define-key' built
+  keymaps as they're requested.")
+
+(defvar magit-key-mode-buf-name "*magit-key*"
+  "Name of the buffer.")
+
+(defvar magit-key-mode-current-args '()
+  "Will contain the arguments to be passed to git.")
+
+(defvar magit-key-mode-current-options '()
+  "Will contain the arguments to be passed to git.")
+
+(defvar magit-log-mode-window-conf nil
+  "Will hold the pre-menu configuration of magit.")
+
+(defvar magit-key-mode-groups
+  '((logging
+     (man-page "git-log")
+     (actions
+      ("l" "Short" magit-log)
+      ("L" "Long" magit-log-long)
+      ("h" "Reflog" magit-reflog)
+      ("rl" "Ranged short" magit-log-ranged)
+      ("rL" "Ranged long" magit-log-long-ranged)
+      ("rh" "Ranged reflog" magit-reflog-ranged))
+     (switches
+      ("-m" "Only merge commits" "--merges")
+      ("-f" "First parent" "--first-parent")
+      ("-i" "Case insensitive patterns" "-i")
+      ("-pr" "Pickaxe regex" "--pickaxe-regex")
+      ("-n" "Name only" "--name-only")
+      ("-am" "All match" "--all-match")
+      ("-al" "All" "--all"))
+     (arguments
+      ("=r" "Relative" "--relative=" read-directory-name)
+      ("=c" "Committer" "--committer=" read-from-minibuffer)
+      ("=>" "Since" "--since=" read-from-minibuffer)
+      ("=<" "Before" "--before=" read-from-minibuffer)
+      ("=s" "Pickaxe search" "-S" read-from-minibuffer)
+      ("=a" "Author" "--author=" read-from-minibuffer)
+      ("=g" "Grep" "--grep=" read-from-minibuffer)))
+
+    (running
+     (actions
+      ("!" "Command from root" magit-shell-command)
+      (":" "Git command" magit-git-command)
+      ("g" "git gui" magit-run-git-gui)
+      ("k" "gitk" magit-run-gitk)))
+
+    (fetching
+     (man-page "git-fetch")
+     (actions
+      ("f" "Current" magit-fetch-current)
+      ("a" "All" magit-remote-update)
+      ("o" "Other" magit-fetch))
+     (switches
+      ("-p" "Prune" "--prune")))
+
+    (pushing
+     (man-page "git-push")
+     (actions
+      ("P" "Push" magit-push)
+      ("t" "Push tags" magit-push-tags))
+     (switches
+      ("-f" "Force" "--force")
+      ("-d" "Dry run" "-n")
+      ("-u" "Set upstream" "-u")))
+
+    (pulling
+     (man-page "git-pull")
+     (actions
+      ("F" "Pull" magit-pull))
+     (switches
+      ("-r" "Rebase" "--rebase")))
+
+    (branching
+     (man-page "git-branch")
+     (actions
+      ("v" "Branch manager" magit-branch-manager)
+      ("c" "Create" magit-create-branch)
+      ("r" "Rename" magit-move-branch)
+      ("k" "Delete" magit-delete-branch)
+      ("b" "Checkout" magit-checkout)))
+
+    (remoting
+     (man-page "git-remote")
+     (actions
+      ("v" "Branch manager" magit-branch-manager)
+      ("a" "Add" magit-add-remote)
+      ("r" "Rename" magit-rename-remote)
+      ("k" "Remove" magit-remove-remote)))
+
+    (tagging
+     (man-page "git-tag")
+     (actions
+      ("t" "Lightweight" magit-tag)
+      ("a" "Annotated" magit-annotated-tag))
+     (switches
+      ("-f" "Force" "-f")))
+
+    (stashing
+     (man-page "git-stash")
+     (actions
+      ("z" "Save" magit-stash)
+      ("s" "Snapshot" magit-stash-snapshot))
+     (switches
+      ("-k" "Keep index" "--keep-index")
+      ("-u" "Include untracked files" "--include-untracked")
+      ("-a" "Include all files" "--all")))
+
+    (merging
+     (man-page "git-merge")
+     (actions
+      ("m" "Merge" magit-manual-merge))
+     (switches
+      ("-ff" "Fast-forward only" "--ff-only")
+      ("-nf" "No fast-forward" "--no-ff")
+      ("-sq" "Squash" "--squash"))
+     (arguments
+      ("-st" "Strategy" "--strategy=" read-from-minibuffer)))
+
+    (rewriting
+     (actions
+      ("b" "Begin" magit-rewrite-start)
+      ("s" "Stop" magit-rewrite-stop)
+      ("a" "Abort" magit-rewrite-abort)
+      ("f" "Finish" magit-rewrite-finish)
+      ("*" "Set unused" magit-rewrite-set-unused)
+      ("." "Set used" magit-rewrite-set-used)))
+
+    (submodule
+     (man-page "git-submodule")
+     (actions
+      ("u" "Update" magit-submodule-update)
+      ("b" "Both update and init" magit-submodule-update-init)
+      ("i" "Init" magit-submodule-init)
+      ("s" "Sync" magit-submodule-sync)))
+
+    (bisecting
+     (man-page "git-bisect")
+     (actions
+      ("b" "Bad" magit-bisect-bad)
+      ("g" "Good" magit-bisect-good)
+      ("k" "Skip" magit-bisect-skip)
+      ("l" "Log" magit-bisect-log)
+      ("r" "Reset" magit-bisect-reset)
+      ("s" "Start" magit-bisect-start)
+      ("u" "Run" magit-bisect-run)
+      ("v" "Visualize" magit-bisect-visualize))))
+  "Holds the key, help, function mapping for the log-mode. If you
+  modify this make sure you reset `magit-key-mode-key-maps' to
+  nil.")
+
+(defun magit-key-mode-delete-group (group)
+  "Delete a group from `magit-key-mode-key-maps'."
+  (let ((items (assoc group magit-key-mode-groups)))
+    (when items
+      ;; reset the cache
+      (setq magit-key-mode-key-maps nil)
+      ;; delete the whole group
+      (setq magit-key-mode-groups
+            (delq items magit-key-mode-groups))
+      ;; unbind the defun
+      (magit-key-mode-de-generate group))
+    magit-key-mode-groups))
+
+(defun magit-key-mode-add-group (group)
+  "Add a new group to `magit-key-mode-key-maps'. If there's
+already a group of that name then this will completely remove it
+and put in its place an empty one of the same name."
+  (when (assoc group magit-key-mode-groups)
+    (magit-key-mode-delete-group group))
+  (setq magit-key-mode-groups
+        (cons (list group (list 'actions)) magit-key-mode-groups)))
+
+(defun magit-key-mode-key-defined-p (for-group key)
+  "If KEY is defined as any of switch, argument or action within
+FOR-GROUP then return t"
+  (catch 'result
+    (let ((options (magit-key-mode-options-for-group for-group)))
+      (dolist (type '(actions switches arguments))
+        (when (assoc key (assoc type options))
+          (throw 'result t))))))
+
+(defun magit-key-mode-update-group (for-group thing &rest args)
+  "Abstraction for setting values in `magit-key-mode-key-maps'."
+  (let* ((options (magit-key-mode-options-for-group for-group))
+         (things (assoc thing options))
+         (key (car args)))
+    (if (cdr things)
+        (if (magit-key-mode-key-defined-p for-group key)
+            (error "%s is already defined in the %s group." key for-group)
+          (setcdr (cdr things) (cons args (cddr things))))
+      (setcdr things (list args)))
+    (setq magit-key-mode-key-maps nil)
+    things))
+
+(defun magit-key-mode-insert-argument (for-group key desc arg read-func)
+  "Add a new binding (KEY) in FOR-GROUP which will use READ-FUNC
+to receive input to apply to argument ARG git is run. DESC should
+be a brief description of the binding."
+  (magit-key-mode-update-group for-group 'arguments key desc arg read-func))
+
+(defun magit-key-mode-insert-switch (for-group key desc switch)
+  "Add a new binding (KEY) in FOR-GROUP which will add SWITCH to git's
+command line when it runs. DESC should be a brief description of
+the binding."
+  (magit-key-mode-update-group for-group 'switches key desc switch))
+
+(defun magit-key-mode-insert-action (for-group key desc func)
+  "Add a new binding (KEY) in FOR-GROUP which will run command
+FUNC. DESC should be a brief description of the binding."
+  (magit-key-mode-update-group for-group 'actions key desc func))
+
+(defun magit-key-mode-options-for-group (for-group)
+  "Retrieve the options (switches, commands and arguments) for
+the group FOR-GROUP."
+  (or (cdr (assoc for-group magit-key-mode-groups))
+      (error "Unknown group '%s'" for-group)))
+
+(defun magit-key-mode-help (for-group)
+  "Provide help for a key (which the user is prompted for) within
+FOR-GROUP."
+  (let* ((opts (magit-key-mode-options-for-group for-group))
+         (man-page (cadr (assoc 'man-page opts)))
+         (seq (read-key-sequence
+               (format "Enter command prefix%s: "
+                       (if man-page
+                         (format ", `?' for man `%s'" man-page)
+                         ""))))
+         (actions (cdr (assoc 'actions opts))))
+    (cond
+      ;; if it is an action popup the help for the to-be-run function
+      ((assoc seq actions) (describe-function (nth 2 (assoc seq actions))))
+      ;; if there is "?" show a man page if there is one
+      ((equal seq "?")
+       (if man-page
+         (man man-page)
+         (error "No man page associated with `%s'" for-group)))
+      (t (error "No help associated with `%s'" seq)))))
+
+(defun magit-key-mode-exec-at-point ()
+  "Run action/args/option at point."
+  (interactive)
+  (let* ((key (or (get-text-property (point) 'key-group-executor)
+                  (error "Nothing at point to do.")))
+         (def (lookup-key (current-local-map) key)))
+    (call-interactively def)))
+(defun magit-key-mode-jump-to-next-exec ()
+  "Jump to the next action/args/option point."
+  (interactive)
+  (let* ((oldp (point))
+         (old  (get-text-property oldp 'key-group-executor))
+         (p    (if (= oldp (point-max)) (point-min) (1+ oldp))))
+    (while (let ((new (get-text-property p 'key-group-executor)))
+             (and (not (= p oldp)) (or (not new) (eq new old))))
+      (setq p (if (= p (point-max)) (point-min) (1+ p))))
+    (goto-char p)
+    (skip-chars-forward " ")))
+
+(defun magit-key-mode-build-keymap (for-group)
+  "Construct a normal looking keymap for the key mode to use and
+put it in magit-key-mode-key-maps for fast lookup."
+  (let* ((options (magit-key-mode-options-for-group for-group))
+         (actions (cdr (assoc 'actions options)))
+         (switches (cdr (assoc 'switches options)))
+         (arguments (cdr (assoc 'arguments options)))
+         (map (make-sparse-keymap)))
+    (suppress-keymap map 'nodigits)
+    ;; ret dwim
+    (define-key map (kbd "RET") 'magit-key-mode-exec-at-point)
+    ;; tab jumps to the next "button"
+    (define-key map (kbd "TAB") 'magit-key-mode-jump-to-next-exec)
+
+    ;; all maps should `quit' with `C-g' or `q'
+    (define-key map (kbd "C-g") `(lambda ()
+                                   (interactive)
+                                   (magit-key-mode-command nil)))
+    (define-key map (kbd "q")   `(lambda ()
+                                   (interactive)
+                                   (magit-key-mode-command nil)))
+    ;; run help
+    (define-key map (kbd "?") `(lambda ()
+                                 (interactive)
+                                 (magit-key-mode-help ',for-group)))
+
+    (flet ((defkey (k action)
+             (when (and (lookup-key map (car k))
+                        (not (numberp (lookup-key map (car k)))))
+               (message "Warning: overriding binding for `%s' in %S"
+                        (car k) for-group)
+               (ding)
+               (sit-for 2))
+             (define-key map (car k)
+               `(lambda () (interactive) ,action))))
+      (when actions
+        (dolist (k actions)
+          (defkey k `(magit-key-mode-command ',(nth 2 k)))))
+      (when switches
+        (dolist (k switches)
+          (defkey k `(magit-key-mode-add-option ',for-group ,(nth 2 k)))))
+      (when arguments
+        (dolist (k arguments)
+          (defkey k `(magit-key-mode-add-argument
+                      ',for-group ,(nth 2 k) ',(nth 3 k))))))
+
+    (push (cons for-group map) magit-key-mode-key-maps)
+    map))
+
+(defvar magit-key-mode-prefix nil
+  "For internal use.  Holds the prefix argument to the command
+that brought up the key-mode window, so it can be used by the
+command that's eventually invoked.")
+
+(defun magit-key-mode-command (func)
+  (let ((args '()))
+    ;; why can't maphash return a list?!
+    (maphash (lambda (k v)
+               (push (concat k (shell-quote-argument v)) args))
+             magit-key-mode-current-args)
+    (let ((magit-custom-options (append args magit-key-mode-current-options))
+          (current-prefix-arg (or current-prefix-arg magit-key-mode-prefix)))
+      (set-window-configuration magit-log-mode-window-conf)
+      (when func
+        (call-interactively func))
+      (magit-key-mode-kill-buffer))))
+
+(defvar magit-key-mode-current-args nil
+  "A hash-table of current argument set (which will eventually
+  make it to the git command-line).")
+
+(defun magit-key-mode-add-argument (for-group arg-name input-func)
+  (let ((input (funcall input-func (concat arg-name ": "))))
+    (puthash arg-name input magit-key-mode-current-args)
+   (magit-key-mode-redraw for-group)))
+
+(defvar magit-key-mode-current-options '()
+  "Current option set (which will eventually make it to the git
+  command-line).")
+
+(defun magit-key-mode-add-option (for-group option-name)
+  "Toggles the appearance of OPTION-NAME in
+`magit-key-mode-current-options'."
+  (if (not (member option-name magit-key-mode-current-options))
+      (add-to-list 'magit-key-mode-current-options option-name)
+    (setq magit-key-mode-current-options
+          (delete option-name magit-key-mode-current-options)))
+  (magit-key-mode-redraw for-group))
+
+(defun magit-key-mode-kill-buffer ()
+  (interactive)
+  (kill-buffer magit-key-mode-buf-name))
+
+(defvar magit-log-mode-window-conf nil
+  "Pre-popup window configuration.")
+
+(defun magit-key-mode (for-group &optional original-opts)
+  "Mode for magit key selection. All commands, switches and
+options can be toggled/actioned with the key combination
+highlighted before the description."
+  (interactive)
+  ;; save the window config to restore it as was (no need to make this
+  ;; buffer local)
+  (setq magit-log-mode-window-conf
+        (current-window-configuration))
+  ;; setup the mode, draw the buffer
+  (let ((buf (get-buffer-create magit-key-mode-buf-name)))
+    (delete-other-windows)
+    (split-window-vertically)
+    (other-window 1)
+    (switch-to-buffer buf)
+    (kill-all-local-variables)
+    (set (make-local-variable
+          'magit-key-mode-current-options)
+         original-opts)
+    (set (make-local-variable
+          'magit-key-mode-current-args)
+         (make-hash-table))
+    (set (make-local-variable 'magit-key-mode-prefix) current-prefix-arg)
+    (magit-key-mode-redraw for-group))
+  (message
+   (concat
+    "Type a prefix key to toggle it. Run 'actions' with their prefixes. "
+    "'?' for more help.")))
+
+(defun magit-key-mode-get-key-map (for-group)
+  "Get or build the keymap for FOR-GROUP."
+  (or (cdr (assoc for-group magit-key-mode-key-maps))
+      (magit-key-mode-build-keymap for-group)))
+
+(defun magit-key-mode-redraw (for-group)
+  "(re)draw the magit key buffer."
+  (let ((buffer-read-only nil)
+        (old-point (point))
+        (is-first (zerop (buffer-size)))
+        (actions-p nil))
+    (erase-buffer)
+    (make-local-variable 'font-lock-defaults)
+    (use-local-map (magit-key-mode-get-key-map for-group))
+    (setq actions-p (magit-key-mode-draw for-group))
+    (delete-trailing-whitespace)
+    (setq mode-name "magit-key-mode" major-mode 'magit-key-mode)
+    (if (and is-first actions-p)
+      (progn (goto-char actions-p)
+             (magit-key-mode-jump-to-next-exec))
+      (goto-char old-point)))
+  (setq buffer-read-only t)
+  (fit-window-to-buffer))
+
+(defun magit-key-mode-draw-header (header)
+  "Draw a header with the correct face."
+  (insert (propertize header 'face 'font-lock-keyword-face) "\n"))
+
+(defvar magit-key-mode-args-in-cols nil
+  "When true, draw arguments in columns as with switches and
+  options.")
+
+(defun magit-key-mode-draw-args (args)
+  "Draw the args part of the menu."
+  (magit-key-mode-draw-buttons
+   "Args"
+   args
+   (lambda (x)
+     (format "(%s) %s"
+             (nth 2 x)
+             (propertize (gethash (nth 2 x) magit-key-mode-current-args "")
+                         'face 'widget-field)))
+   (not magit-key-mode-args-in-cols)))
+
+(defun magit-key-mode-draw-switches (switches)
+  "Draw the switches part of the menu."
+  (magit-key-mode-draw-buttons
+   "Switches"
+   switches
+   (lambda (x)
+     (format "(%s)" (let ((s (nth 2 x)))
+                      (if (member s magit-key-mode-current-options)
+                        (propertize s 'face 'font-lock-warning-face)
+                        s))))))
+
+(defun magit-key-mode-draw-actions (actions)
+  "Draw the actions part of the menu."
+  (magit-key-mode-draw-buttons "Actions" actions nil))
+
+(defun magit-key-mode-draw-buttons (section xs maker
+                                    &optional one-col-each)
+  (when xs
+    (magit-key-mode-draw-header section)
+    (magit-key-mode-draw-in-cols
+     (mapcar (lambda (x)
+               (let* ((head (propertize (car x) 'face 'font-lock-builtin-face))
+                      (desc (nth 1 x))
+                      (more (and maker (funcall maker x)))
+                      (text (format " %s: %s%s%s"
+                                    head desc (if more " " "") (or more ""))))
+                 (propertize text 'key-group-executor (car x))))
+             xs)
+     one-col-each)))
+
+(defun magit-key-mode-draw-in-cols (strings one-col-each)
+  "Given a list of strings, print in columns (using `insert'). If
+ONE-COL-EACH is true then don't columify, but rather, draw each
+item on one line."
+  (let ((longest-act (apply 'max (mapcar 'length strings))))
+    (while strings
+      (let ((str (car strings)))
+        (let ((padding (make-string (- (+ longest-act 3) (length str)) ? )))
+          (insert str)
+          (if (or one-col-each
+                  (and (> (+ (length padding) ;
+                             (current-column)
+                             longest-act)
+                          (window-width))
+                       (cdr strings)))
+              (insert "\n")
+            (insert padding))))
+      (setq strings (cdr strings))))
+  (insert "\n"))
+
+(defun magit-key-mode-draw (for-group)
+  "Function used to draw actions, switches and parameters.
+
+Returns the point before the actions part, if any."
+  (let* ((options (magit-key-mode-options-for-group for-group))
+         (switches (cdr (assoc 'switches options)))
+         (arguments (cdr (assoc 'arguments options)))
+         (actions (cdr (assoc 'actions options)))
+         (p nil))
+    (magit-key-mode-draw-switches switches)
+    (magit-key-mode-draw-args arguments)
+    (when actions (setq p (point-marker)))
+    (magit-key-mode-draw-actions actions)
+    (insert "\n")
+    p))
+
+(defun magit-key-mode-de-generate (group)
+  "Unbind the function for GROUP."
+  (fmakunbound
+   (intern (concat "magit-key-mode-popup-" (symbol-name group)))))
+
+(defun magit-key-mode-generate (group)
+  "Generate the key-group menu for GROUP"
+  (let ((opts (magit-key-mode-options-for-group group)))
+    (eval
+     `(defun ,(intern (concat "magit-key-mode-popup-" (symbol-name group))) nil
+        ,(concat "Key menu for " (symbol-name group))
+        (interactive)
+        (magit-key-mode (quote ,group))))))
+
+;; create the interactive functions for the key mode popups (which are
+;; applied in the top-level key maps)
+(mapc (lambda (g)
+        (magit-key-mode-generate (car g)))
+      magit-key-mode-groups)
+
+(provide 'magit-key-mode)
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-key-mode.elc b/.emacs.d/elpa/magit-1.2.0/magit-key-mode.elc
new file mode 100644
index 0000000..7a2238c
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-key-mode.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-pkg.el b/.emacs.d/elpa/magit-1.2.0/magit-pkg.el
new file mode 100644
index 0000000..11ad324
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-pkg.el
@@ -0,0 +1 @@
+(define-package "magit" "1.2.0" "Control Git from Emacs.")
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-pkg.elc b/.emacs.d/elpa/magit-1.2.0/magit-pkg.elc
new file mode 100644
index 0000000..54f5860
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-pkg.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-stgit.el b/.emacs.d/elpa/magit-1.2.0/magit-stgit.el
new file mode 100644
index 0000000..b105b71
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-stgit.el
@@ -0,0 +1,288 @@
+;;; magit-stgit.el --- StGit plug-in for Magit
+
+;; Copyright (C) 2011  Lluis Vilanova
+;;
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This plug-in provides StGit functionality as a separate component of Magit.
+
+;; Available actions:
+;; - visit: Shows the patch at point in the series (stg show)
+;; - apply: Goes to the patch at point in the series (stg goto)
+;; - discard: Deletes the marked/at point patch in the series (stg delete)
+
+;; Available commands:
+;; - `magit-stgit-refresh': Refresh the marked/at point patch in the series
+;;   (stg refresh)
+;; - `magit-stgit-repair': Repair the StGit metadata (stg repair)
+;; - `magit-stgit-rebase': Rebase the whole series (stg rebase)
+
+;; TODO:
+;; - Let the user select which files must be included in a refresh.
+;; - Missing actions for `magit-show-item-or-scroll-up' and
+;;   `magit-show-item-or-scroll-down'.
+;; - Marking a patch is slow and refreshes all buffers, which resets their
+;;   position (i.e., the buffer is shown from its first line).
+
+;;; Code:
+
+(require 'magit)
+(eval-when-compile
+  (require 'cl))
+
+;;; Customizables:
+
+(defcustom magit-stgit-executable "stg"
+  "The name of the StGit executable."
+  :group 'magit
+  :type 'string)
+
+(defface magit-stgit-applied
+  '((t :inherit magit-diff-add))
+  "Face for an applied stgit patch."
+  :group 'magit-faces)
+
+(defface magit-stgit-current
+  '((t :inherit magit-item-highlight))
+  "Face for the current stgit patch."
+  :group 'magit-faces)
+
+(defface magit-stgit-other
+  '((t :inherit magit-diff-del))
+  "Face for a non-applied stgit patch."
+  :group 'magit-faces)
+
+(defface magit-stgit-marked
+  '((t :inherit magit-item-mark))
+  "Face for a marked stgit patch."
+  :group 'magit-faces)
+
+(defface magit-stgit-empty
+  '((t :inherit magit-item-mark))
+  "Face for an empty stgit patch."
+  :group 'magit-faces)
+
+;;; Common code:
+
+(defvar magit-stgit--enabled nil
+  "Whether this buffer has StGit support.")
+(make-variable-buffer-local 'magit-stgit--enabled)
+
+(defvar magit-stgit-mode)
+
+(defun magit-stgit--enabled ()
+  "Whether this buffer has StGit support enabled."
+  (if (assoc 'magit-stgit--enabled (buffer-local-variables))
+      magit-stgit--enabled
+    (setq magit-stgit--enabled
+          (and magit-stgit-mode
+               (not (null
+                     (member (concat (magit-get-current-branch) ".stgit")
+                             (mapcar #'(lambda (line)
+                                         (string-match "^\\*?\s*\\([^\s]*\\)"
+                                                       line)
+                                         (match-string 1 line))
+                                     (magit-git-lines "branch")))))))))
+
+(defun magit-stgit--enabled-reset ()
+  "Reset the StGit enabled state."
+  (kill-local-variable 'magit-stgit--enabled))
+
+(defvar magit-stgit--marked-patch nil
+  "The (per-buffer) currently marked patch in an StGit series.")
+(make-variable-buffer-local 'magit-stgit--marked-patch)
+
+;;; Menu:
+
+(easy-menu-define magit-stgit-extension-menu
+  nil
+  "StGit extension menu"
+  '("StGit"
+    :active (magit-stgit--enabled)
+
+    ["Refresh patch" magit-stgit-refresh
+     :help "Refresh the contents of a patch in an StGit series"]
+    ["Repair" magit-stgit-repair
+     :help "Repair StGit metadata if branch was modified with git commands"]
+    ["Rebase series" magit-stgit-rebase
+     :help "Rebase an StGit patch series"]
+    ))
+
+(easy-menu-add-item 'magit-mode-menu
+                    '("Extensions")
+                    magit-stgit-extension-menu)
+
+;;; Series section:
+
+(defun magit-stgit--wash-patch ()
+  (if (search-forward-regexp "^\\(.\\)\\(.\\) \\([^\s]*\\)\\(\s*# ?\\)\\(.*\\)"
+                             (line-end-position) t)
+      (let* ((empty-str "[empty] ")
+             (indent-str (make-string (string-bytes empty-str) ?\ ))
+             (empty (match-string 1))
+             (state (match-string 2))
+             (patch (match-string 3))
+             (descr (match-string 5)))
+        (delete-region (line-beginning-position) (line-end-position))
+        (insert
+         (cond ((string= empty "0")
+                (propertize (concat empty-str " " state " " descr) 'face 'magit-stgit-empty))
+               ((string= magit-stgit--marked-patch patch)
+                (propertize (concat indent-str " " state " " descr) 'face 'magit-stgit-marked))
+               ((string= state "+")
+                (concat indent-str " " (propertize state 'face 'magit-stgit-applied) " " descr))
+               ((string= state ">")
+                (propertize (concat indent-str " " state " " descr) 'face 'magit-stgit-current))
+               ((string= state "-")
+                (concat indent-str " " (propertize state 'face 'magit-stgit-other) " " descr))))
+        (goto-char (line-beginning-position))
+        (magit-with-section patch 'series
+          (magit-set-section-info patch)
+          (goto-char (line-end-position)))
+        (forward-line))
+    (delete-region (line-beginning-position) (1+ (line-end-position))))
+  t)
+
+(defun magit-stgit--wash-series ()
+    (let ((magit-old-top-section nil))
+      (magit-wash-sequence #'magit-stgit--wash-patch)))
+
+(magit-define-inserter series ()
+  (when (executable-find magit-stgit-executable)
+    (magit-insert-section 'series
+                          "Series:" 'magit-stgit--wash-series
+                          magit-stgit-executable "series" "-a" "-d" "-e")))
+
+;;; Actions:
+
+;; Copy of `magit-refresh-commit-buffer' (version 1.0.0)
+(defun magit-stgit--refresh-patch-buffer (patch)
+  (magit-create-buffer-sections
+    (magit-insert-section nil nil
+                       'magit-wash-commit
+                       magit-stgit-executable
+                       "show"
+                       patch)))
+
+;; Copy of `magit-show-commit' (version 1.0.0)
+(defun magit-stgit--show-patch (patch &optional scroll)
+  (when (magit-section-p patch)
+    (setq patch (magit-section-info patch)))
+  (let ((dir default-directory)
+        (buf (get-buffer-create magit-commit-buffer-name)))
+    (cond ((and (equal magit-currently-shown-commit patch)
+                ;; if it's empty then the buffer was killed
+                (with-current-buffer buf
+                  (> (length (buffer-string)) 1)))
+           (let ((win (get-buffer-window buf)))
+             (cond ((not win)
+                    (display-buffer buf))
+                   (scroll
+                    (with-selected-window win
+                      (funcall scroll))))))
+          (t
+           (setq magit-currently-shown-commit patch)
+           (display-buffer buf)
+           (with-current-buffer buf
+             (set-buffer buf)
+             (goto-char (point-min))
+             (magit-mode-init dir 'magit-commit-mode
+                              #'magit-stgit--refresh-patch-buffer patch))))))
+
+(magit-add-action (item info "visit")
+  ((series)
+   (magit-stgit--show-patch info)
+   (pop-to-buffer magit-commit-buffer-name)))
+
+(magit-add-action (item info "apply")
+  ((series)
+   (magit-run magit-stgit-executable "goto" info)))
+
+(magit-add-action (item info "discard")
+  ((series)
+   (let ((patch (or magit-stgit--marked-patch info)))
+     (if (yes-or-no-p (format "Delete patch '%s' in series? " patch))
+         (progn
+           (if (string= magit-stgit--marked-patch patch)
+               (setq magit-stgit--marked-patch nil))
+           (magit-run magit-stgit-executable "delete" patch))))))
+
+(defun magit-stgit--set-marked-patch (patch)
+  (setq magit-stgit--marked-patch
+        (if (string= magit-stgit--marked-patch patch)
+            nil
+          patch)))
+
+(magit-add-action (item info "mark")
+  ((series)
+   (magit-stgit--set-marked-patch info)
+   (magit-refresh-all)))
+
+;;; Commands:
+
+(defun magit-stgit-refresh ()
+  "Refresh the contents of a patch in an StGit series.
+If there is no marked patch in the series, refreshes the current
+patch.
+Otherwise, refreshes the marked patch."
+  (interactive)
+  (if magit-stgit--marked-patch
+      (magit-run magit-stgit-executable "refresh" "-p" magit-stgit--marked-patch)
+    (magit-run magit-stgit-executable "refresh")))
+
+(defun magit-stgit-repair ()
+  "Repair StGit metadata if branch was modified with git commands.
+In the case of Git commits these will be imported as new patches
+into the series."
+  (interactive)
+  (message "Repairing series...")
+  (magit-run magit-stgit-executable "repair")
+  (message ""))
+
+(defun magit-stgit-rebase ()
+  "Rebase an StGit patch series."
+  (interactive)
+  (if (magit-get-current-remote)
+      (progn
+        (if (yes-or-no-p "Update remotes? ")
+            (progn
+              (message "Updating remotes...")
+              (magit-run-git-async "remote" "update")))
+        (magit-run magit-stgit-executable "rebase"
+                   (format "remotes/%s/%s"
+                           (magit-get-current-remote)
+                           (magit-get-current-branch))))))
+
+;;;###autoload
+(define-minor-mode magit-stgit-mode "StGit support for Magit"
+  :lighter " Stg" :require 'magit-stgit
+  (or (derived-mode-p 'magit-mode)
+      (error "This mode only makes sense with magit"))
+  (if magit-stgit-mode
+      (progn
+        (add-hook 'magit-after-insert-stashes-hook 'magit-insert-series nil t))
+    (progn
+      (remove-hook 'magit-after-insert-stashes-hook 'magit-insert-series t)))
+  (when (called-interactively-p 'any)
+    (magit-refresh)))
+
+;;;###autoload
+(defun turn-on-magit-stgit ()
+  "Unconditionally turn on `magit-stgit-mode'."
+  (magit-stgit-mode 1))
+
+(provide 'magit-stgit)
+;;; magit-stgit.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-stgit.elc b/.emacs.d/elpa/magit-1.2.0/magit-stgit.elc
new file mode 100644
index 0000000..66460ea
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-stgit.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-svn.el b/.emacs.d/elpa/magit-1.2.0/magit-svn.el
new file mode 100644
index 0000000..d08c048
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-svn.el
@@ -0,0 +1,240 @@
+;;; magit-svn.el --- git-svn plug-in for Magit
+
+;; Copyright (C) 2008  Alex Ott
+;; Copyright (C) 2009  Alexey Voinov
+;; Copyright (C) 2009  John Wiegley
+;; Copyright (C) 2008  Linh Dang
+;; Copyright (C) 2008  Marcin Bachry
+;; Copyright (C) 2008, 2009  Marius Vollmer
+;; Copyright (C) 2010  Yann Hodique
+;;
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This plug-in provides git-svn functionality as a separate component of Magit
+
+;;; Code:
+
+(require 'magit)
+(eval-when-compile
+  (require 'cl))
+
+;; git svn commands
+
+(defun magit-svn-find-rev (rev &optional branch)
+  (interactive
+   (list (read-string "SVN revision: ")
+         (if current-prefix-arg
+             (read-string "In branch: "))))
+  (let* ((sha (apply 'magit-git-string
+                     `("svn"
+                       "find-rev"
+                       ,(concat "r" rev)
+                       ,@(when branch (list branch))))))
+    (if sha
+        (magit-show-commit
+         (magit-with-section sha 'commit
+           (magit-set-section-info sha)
+           sha))
+      (error "Revision %s could not be mapped to a commit" rev))))
+
+(defun magit-svn-create-branch (name)
+  (interactive "sBranch name: ")
+  (magit-run-git "svn" "branch" name))
+
+(defun magit-svn-rebase ()
+  (interactive)
+  (magit-run-git-async "svn" "rebase"))
+
+(defun magit-svn-dcommit ()
+  (interactive)
+  (magit-run-git-async "svn" "dcommit"))
+
+(defun magit-svn-enabled ()
+  (not (null (magit-svn-get-ref-info t))))
+
+(defun magit-svn-expand-braces-in-branches (branch)
+  (if (not (string-match "\\(.+\\){\\(.+,.+\\)}\\(.*\\):\\(.*\\)\\\*" branch))
+      (list branch)
+    (let ((prefix (match-string 1 branch))
+          (suffix (match-string 3 branch))
+          (rhs (match-string 4 branch))
+          (pieces (split-string (match-string 2 branch) ",")))
+      (mapcar (lambda (p) (concat prefix p suffix ":" rhs p)) pieces))))
+
+(defun magit-svn-get-local-ref (url)
+  (let* ((branches (cons (magit-get "svn-remote" "svn" "fetch")
+                        (magit-get-all "svn-remote" "svn" "branches")))
+         (branches (apply 'nconc
+                          (mapcar 'magit-svn-expand-braces-in-branches
+                                  branches)))
+        (base-url (magit-get "svn-remote" "svn" "url"))
+        (result nil))
+    (while branches
+      (let* ((pats (split-string (pop branches) ":"))
+             (src (replace-regexp-in-string "\\*" "\\\\(.*\\\\)" (car pats)))
+             (dst (replace-regexp-in-string "\\*" "\\\\1" (cadr pats)))
+             (base-url (replace-regexp-in-string "\\+" "\\\\+" base-url))
+             (base-url (replace-regexp-in-string "//.+@" "//" base-url))
+             (pat1 (concat "^" src "$"))
+             (pat2 (cond ((equal src "") (concat "^" base-url "$"))
+                         (t (concat "^" base-url "/" src "$")))))
+        (cond ((string-match pat1 url)
+               (setq result (replace-match dst nil nil url))
+               (setq branches nil))
+              ((string-match pat2 url)
+               (setq result (replace-match dst nil nil url))
+               (setq branches nil)))))
+    result))
+
+(defvar magit-svn-get-ref-info-cache nil
+  "A cache for svn-ref-info.
+As `magit-get-svn-ref-info' might be considered a quite
+expensive operation a cache is taken so that `magit-status'
+doesn't repeatedly call it.")
+
+(defun magit-svn-get-ref-info (&optional use-cache)
+  "Gather details about the current git-svn repository.
+Return nil if there isn't one.  Keys of the alist are ref-path,
+trunk-ref-name and local-ref-name.
+If USE-CACHE is non-nil then return the value of `magit-get-svn-ref-info-cache'."
+  (if (and use-cache magit-svn-get-ref-info-cache)
+      magit-svn-get-ref-info-cache
+    (let* ((fetch (magit-get "svn-remote" "svn" "fetch"))
+           (url)
+           (revision))
+      (when fetch
+        (let* ((ref (cadr (split-string fetch ":")))
+               (ref-path (file-name-directory ref))
+               (trunk-ref-name (file-name-nondirectory ref)))
+          (set (make-local-variable
+                'magit-svn-get-ref-info-cache)
+                (list
+                 (cons 'ref-path ref-path)
+                 (cons 'trunk-ref-name trunk-ref-name)
+                 ;; get the local ref from the log. This is actually
+                 ;; the way that git-svn does it.
+                 (cons 'local-ref
+                       (with-temp-buffer
+                         (insert (or (magit-git-string "log" "--first-parent"
+                                                       "--grep" "git-svn" "-1")
+                                     ""))
+                         (goto-char (point-min))
+                         (cond ((re-search-forward "git-svn-id: \\(.+/.+?\\)@\\([0-9]+\\)" nil t)
+                                (setq url (match-string 1)
+                                      revision (match-string 2))
+                                (magit-svn-get-local-ref url))
+                               (t
+                                (setq url (magit-get "svn-remote" "svn" "url"))
+                                nil))))
+                 (cons 'revision revision)
+                 (cons 'url url))))))))
+
+(defun magit-svn-get-ref (&optional use-cache)
+  "Get the best guess remote ref for the current git-svn based branch.
+If USE-CACHE is non nil, use the cached information."
+  (let ((info (magit-svn-get-ref-info use-cache)))
+    (cdr (assoc 'local-ref info))))
+
+(magit-define-inserter svn-unpulled (&optional use-cache)
+  (when (magit-svn-enabled)
+    (apply #'magit-git-section
+           'svn-unpulled "Unpulled commits (SVN):" 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    (format "HEAD..%s" (magit-svn-get-ref use-cache)))))))
+
+(magit-define-inserter svn-unpushed (&optional use-cache)
+  (when (magit-svn-enabled)
+    (apply #'magit-git-section
+           'svn-unpushed "Unpushed commits (SVN):" 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    (format "%s..HEAD" (magit-svn-get-ref use-cache)))))))
+
+(magit-define-section-jumper svn-unpushed  "Unpushed commits (SVN)")
+
+(defun magit-svn-remote-string ()
+  (let ((svn-info (magit-svn-get-ref-info)))
+    (when svn-info
+      (concat (cdr (assoc 'url svn-info))
+              " @ "
+              (cdr (assoc 'revision svn-info))))))
+
+(defun magit-svn-remote-update ()
+  (interactive)
+  (when (magit-svn-enabled)
+    (magit-run-git-async "svn" "fetch")))
+
+(easy-menu-define magit-svn-extension-menu
+  nil
+  "Git SVN extension menu"
+  '("Git SVN"
+    :visible magit-svn-mode
+    ["Create branch" magit-svn-create-branch (magit-svn-enabled)]
+    ["Rebase" magit-svn-rebase (magit-svn-enabled)]
+    ["Fetch" magit-svn-remote-update (magit-svn-enabled)]
+    ["Commit" magit-svn-dcommit (magit-svn-enabled)]))
+
+(easy-menu-add-item 'magit-mode-menu
+                    '("Extensions")
+                    magit-svn-extension-menu)
+
+;; add the group and its keys
+(progn
+  ;; (re-)create the group
+  (magit-key-mode-add-group 'svn)
+
+  (magit-key-mode-insert-action 'svn "r" "Rebase" 'magit-svn-rebase)
+  (magit-key-mode-insert-action 'svn "c" "DCommit" 'magit-svn-dcommit)
+  (magit-key-mode-insert-action 'svn "f" "Fetch" 'magit-svn-remote-update)
+  (magit-key-mode-insert-action 'svn "s" "Find rev" 'magit-svn-find-rev)
+  (magit-key-mode-insert-action 'svn "B" "Create branch" 'magit-svn-create-branch)
+
+  ;; generate and bind the menu popup function
+  (magit-key-mode-generate 'svn))
+
+(defvar magit-svn-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "N") 'magit-key-mode-popup-svn)
+    map))
+
+;;;###autoload
+(define-minor-mode magit-svn-mode "SVN support for Magit"
+  :lighter " SVN" :require 'magit-svn :keymap 'magit-svn-mode-map
+  (or (derived-mode-p 'magit-mode)
+      (error "This mode only makes sense with magit"))
+  (let ((unpulled-hook (lambda () (magit-insert-svn-unpulled t)))
+        (unpushed-hook (lambda () (magit-insert-svn-unpushed t)))
+        (remote-hook 'magit-svn-remote-string))
+    (if magit-svn-mode
+        (progn
+          (add-hook 'magit-after-insert-unpulled-commits-hook unpulled-hook nil t)
+          (add-hook 'magit-after-insert-unpushed-commits-hook unpushed-hook nil t)
+          (add-hook 'magit-remote-string-hook remote-hook nil t))
+      (progn
+        (remove-hook 'magit-after-insert-unpulled-commits-hook unpulled-hook t)
+        (remove-hook 'magit-after-insert-unpushed-commits-hook unpushed-hook t)
+        (remove-hook 'magit-remote-string-hook remote-hook t)))
+    (when (called-interactively-p 'any)
+      (magit-refresh))))
+
+;;;###autoload
+(defun turn-on-magit-svn ()
+  "Unconditionally turn on `magit-svn-mode'."
+  (magit-svn-mode 1))
+
+(provide 'magit-svn)
+;;; magit-svn.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-svn.elc b/.emacs.d/elpa/magit-1.2.0/magit-svn.elc
new file mode 100644
index 0000000..18c19d2
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-svn.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-topgit.el b/.emacs.d/elpa/magit-1.2.0/magit-topgit.el
new file mode 100644
index 0000000..6f0080c
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-topgit.el
@@ -0,0 +1,191 @@
+;;; magit-topgit.el --- topgit plug-in for Magit
+
+;; Copyright (C) 2010  Nathan Weizenbaum
+;; Copyright (C) 2010  Yann Hodique
+;;
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This plug-in provides topgit functionality as a separate component of Magit
+
+;;; Code:
+
+(require 'magit)
+(eval-when-compile
+  (require 'cl))
+
+(defcustom magit-topgit-executable "tg"
+  "The name of the TopGit executable."
+  :group 'magit
+  :type 'string)
+
+(defcustom magit-topgit-branch-prefix "t/"
+  "Convention prefix for topic branch creation."
+  :group 'magit
+  :type 'string)
+
+(defface magit-topgit-current
+  '((t :weight bold :inherit magit-branch))
+  "Face for section titles."
+  :group 'magit-faces)
+
+;;; Topic branches (using topgit)
+
+(defun magit-topgit-in-topic-p ()
+  (and (file-exists-p ".topdeps")
+       (executable-find magit-topgit-executable)))
+
+(defun magit-topgit-create-branch (branch parent)
+  (when (zerop (or (string-match magit-topgit-branch-prefix branch) -1))
+    (magit-run* (list magit-topgit-executable "create"
+                      branch (magit-rev-to-git parent))
+                nil nil nil t)
+    t))
+
+(defun magit-topgit-pull ()
+  (when (magit-topgit-in-topic-p)
+    (magit-run* (list magit-topgit-executable "update")
+                nil nil nil t)
+    t))
+
+(defun magit-topgit-push ()
+  (when (magit-topgit-in-topic-p)
+    (let* ((branch (or (magit-get-current-branch)
+                       (error "Don't push a detached head.  That's gross")))
+           (remote (magit-get "topgit" "remote"))
+           (push-remote (if (or current-prefix-arg (not remote))
+                            (magit-read-remote (format "Push %s to" branch))
+                          remote)))
+      (when (and (not remote)
+                 (not current-prefix-arg))
+        (magit-set push-remote "topgit" "remote"))
+      (magit-run magit-topgit-executable "push" "-r" push-remote))
+    t))
+
+(defun magit-topgit-remote-update (&optional remote)
+  (when (magit-topgit-in-topic-p)
+    (let* ((remote (magit-get "topgit" "remote"))
+           (remote-update (if (or current-prefix-arg (not remote))
+                              (magit-read-remote)
+                            remote)))
+      (if (and (not remote)
+               (not current-prefix-arg))
+          (progn
+            (magit-set remote-update "topgit" "remote")
+            (magit-run magit-topgit-executable "remote"
+                       "--populate" remote-update)))
+      (magit-run magit-topgit-executable "remote" remote-update))
+    ;; We return nil anyway, as we also want regular "git remote update" to
+    ;; happen
+    nil))
+
+(defun magit-topgit-parse-flags (flags-string)
+  (let ((flags (string-to-list flags-string))
+        (void-flag ?\ ))
+    (list :current (not (eq (nth 0 flags) void-flag))
+          :empty (not (eq (nth 1 flags) void-flag)))))
+
+(defun magit-topgit-wash-topic ()
+  (let ((fmt "^\\(.\\{7\\}\\)\\s-\\(\\S-+\\)\\s-+\\(.*\\)"))
+    (if (search-forward-regexp fmt (line-end-position) t)
+        (let ((flags (magit-topgit-parse-flags (match-string 1)))
+              (topic (match-string 2)))
+          (goto-char (line-beginning-position))
+          (delete-char 8)
+          (insert "\t")
+          (goto-char (line-beginning-position))
+          (magit-with-section topic 'topic
+            (magit-set-section-info topic)
+            (let ((beg (1+ (line-beginning-position)))
+                  (end (line-end-position)))
+              (when (plist-get flags :current)
+                (put-text-property beg end 'face 'magit-topgit-current))
+              (when (plist-get flags :empty)
+                (put-text-property beg end 'face `(:strike-through t :inherit ,(get-text-property beg 'face)))))
+            (forward-line)))
+      (delete-region (line-beginning-position) (1+ (line-end-position))))
+    t))
+
+(defun magit-topgit-wash-topics ()
+  (let ((magit-old-top-section nil))
+    (magit-wash-sequence #'magit-topgit-wash-topic)))
+
+(defun magit-topgit-section (section title washer &rest args)
+  (when (executable-find magit-topgit-executable)
+    (let ((magit-git-executable magit-topgit-executable)
+          (magit-git-standard-options nil))
+      (apply 'magit-git-section section title washer args))))
+
+(magit-define-inserter topics ()
+  (magit-topgit-section 'topics
+                        "Topics:" 'magit-topgit-wash-topics
+                        "summary"))
+
+(magit-add-action (item info "discard")
+  ((topic)
+   (when (yes-or-no-p "Discard topic? ")
+     (magit-run* (list magit-topgit-executable "delete" "-f" info)
+                 nil nil nil t))))
+
+(magit-add-action (item info "visit")
+  ((topic)
+   (magit-checkout info)))
+
+(defun magit-topgit-get-top-bases-color (suffix)
+  (list nil nil))
+
+(defun magit-topgit-get-remote-top-bases-color (suffix)
+  (when (string-match "^\\(?:[^/]+\\)/top-bases" suffix)
+    (list nil nil)))
+
+(defconst magit-topgit-ignored-namespace
+  '("top-bases" magit-topgit-get-top-bases-color))
+
+;;;###autoload
+(define-minor-mode magit-topgit-mode "Topgit support for Magit"
+  :lighter " Topgit" :require 'magit-topgit
+  (or (derived-mode-p 'magit-mode)
+      (error "This mode only makes sense with magit"))
+  (if magit-topgit-mode
+      (progn
+        (add-hook 'magit-after-insert-stashes-hook 'magit-insert-topics nil t)
+        (add-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch nil t)
+        (add-hook 'magit-pull-command-hook 'magit-topgit-pull nil t)
+        (add-hook 'magit-remote-update-command-hook 'magit-topgit-remote-update nil t)
+        (add-hook 'magit-push-command-hook 'magit-topgit-push nil t)
+        ;; hide refs for top-bases namespace in any remote
+        (add-hook 'magit-log-remotes-color-hook
+                  'magit-topgit-get-remote-top-bases-color)
+        ;; hide refs in the top-bases namespace, as they're not meant for the user
+        (add-to-list 'magit-refs-namespaces magit-topgit-ignored-namespace))
+    (progn
+        (remove-hook 'magit-after-insert-stashes-hook 'magit-insert-topics t)
+        (remove-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch t)
+        (remove-hook 'magit-pull-command-hook 'magit-topgit-pull t)
+        (remove-hook 'magit-remote-update-command-hook 'magit-topgit-remote-update t)
+        (remove-hook 'magit-push-command-hook 'magit-topgit-push t)
+        (remove-hook 'magit-log-remotes-color-hook
+                     'magit-topgit-get-remote-top-bases-color)
+        (delete magit-topgit-ignored-namespace magit-refs-namespaces)))
+  (when (called-interactively-p 'any)
+    (magit-refresh)))
+
+;;;###autoload
+(defun turn-on-magit-topgit ()
+  "Unconditionally turn on `magit-topgit-mode'."
+  (magit-topgit-mode 1))
+
+(provide 'magit-topgit)
+;;; magit-topgit.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-topgit.elc b/.emacs.d/elpa/magit-1.2.0/magit-topgit.elc
new file mode 100644
index 0000000..80fbb87
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-topgit.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-wip.el b/.emacs.d/elpa/magit-1.2.0/magit-wip.el
new file mode 100644
index 0000000..5c19840
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit-wip.el
@@ -0,0 +1,153 @@
+;;; magit-wip.el --- git-wip plug-in for Magit
+
+;; Copyright (C) 2012  Jonas Bernoulli
+;; Copyright (C) 2012  Ryan C. Thompson
+
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This plug-in provides support for special work-in-progress refs.
+
+;; This requires the third-party git command "git wip" which is available
+;; from https://github.com/bartman/git-wip.
+
+;; The global mode `magit-wip-mode' provides highlighting of wip refs in
+;; Magit buffers while the local mode `magit-wip-save-mode' commits to
+;; such a ref when saving a file-visiting buffer.
+
+;; To enable `magit-wip-save-mode' enable `global-magit-wip-save-mode'
+;; and use the Magit extension mechanism to select the repositories in
+;; which you want to use a work-in-progress ref.  Usually you also want
+;; to enable `magit-wip-mode'.
+;;
+;;   (magit-wip-mode 1)
+;;   (global-magit-wip-save-mode 1)
+;;
+;;   $ git config --add magit.extension wip-save           # or
+;;   $ git config --global --add magit.extension wip-save
+
+;; Note that `global-magit-wip-save-mode' is the only mode that uses the
+;; extension mechanism for file-visiting buffers all other global modes
+;; making use of it to turn on local modes in Magit buffers.
+
+;;; Code:
+
+(require 'magit)
+(require 'format-spec)
+
+;;; Magit Wip Mode.
+
+(defface magit-log-head-label-wip
+  '((((class color) (background light))
+     :box t
+     :background "Grey95"
+     :foreground "LightSkyBlue3")
+    (((class color) (background dark))
+     :box t
+     :background "Grey07"
+     :foreground "LightSkyBlue4"))
+  "Face for git-wip labels shown in log buffer."
+  :group 'magit-faces)
+
+(defun magit-log-get-wip-color (suffix)
+  (list (concat "(WIP) " suffix)
+        'magit-log-head-label-wip))
+
+(defconst magit-wip-refs-namespace
+  '("wip" magit-log-get-wip-color))
+
+;;;###autoload
+(define-minor-mode magit-wip-mode
+  "In Magit log buffers; give wip refs a special appearance."
+  :group 'magit
+  :global t
+  (if magit-wip-mode
+      (add-to-list 'magit-refs-namespaces magit-wip-refs-namespace 'append)
+    (setq magit-refs-namespaces
+          (delete magit-wip-refs-namespace magit-refs-namespaces))))
+
+;;; Magit Wip Save Mode.
+
+(defcustom magit-wip-commit-message "WIP %r"
+  "Commit message for git-wip commits.
+
+The following `format'-like specs are supported:
+%f the full name of the file being saved, and
+%r the name of the file being saved, relative to the repository root
+%g the root of the git repository."
+  :group 'magit
+  :type 'string)
+
+(defcustom magit-wip-echo-area-message "Wrote %f (wip)"
+  "Message shown in the echo area after creating a git-wip commit.
+
+The following `format'-like specs are supported:
+%f the full name of the file being saved, and
+%r the name of the file being saved, relative to the repository root.
+%g the root of the git repository."
+  :group 'magit
+  :type '(choice (const :tag "No message" nil) string))
+
+(defvar magit-wip-save-mode-lighter " Wip")
+
+;;;###autoload
+(define-minor-mode magit-wip-save-mode
+  "Magit support for committing to a work-in-progress ref.
+
+When this minor mode is turned on and a file is saved inside a writable
+git repository then it is also committed to a special work-in-progress
+ref."
+  :lighter magit-wip-save-mode-lighter
+  (if magit-wip-save-mode
+      (add-hook  'after-save-hook 'magit-wip-save-safe t t)
+    (remove-hook 'after-save-hook 'magit-wip-save-safe t)))
+
+;;;###autoload
+(define-globalized-minor-mode global-magit-wip-save-mode
+  magit-wip-save-mode turn-on-magit-wip-save
+  :group 'magit)
+
+(defun turn-on-magit-wip-save ()
+  (when (and (buffer-file-name)
+             (magit-get-top-dir default-directory)
+             (member "wip-save" (magit-get-all "magit.extension")))
+    (if (= (magit-git-exit-code "wip" "-h") 0)
+        (magit-wip-save-mode 1)
+      (message "Git command 'git wip' cannot be found"))))
+
+(defun magit-wip-save-safe ()
+  (condition-case err
+      (magit-wip-save)
+    (error
+     (message "Magit WIP got an error: %S" err))))
+
+(defun magit-wip-save ()
+  (let* ((top-dir (magit-get-top-dir default-directory))
+         (name (file-truename (buffer-file-name)))
+         (spec `((?r . ,(file-relative-name name top-dir))
+                 (?f . ,(buffer-file-name))
+                 (?g . ,top-dir))))
+    (when (and top-dir (file-writable-p top-dir))
+      (save-excursion ; kludge see https://github.com/magit/magit/issues/441
+        (magit-run-git "wip" "save"
+                       (format-spec magit-wip-commit-message spec)
+                       "--editor" "--" name))
+      (when magit-wip-echo-area-message
+        (message (format-spec magit-wip-echo-area-message spec))))))
+
+(provide 'magit-wip)
+;;; magit-wip.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit-wip.elc b/.emacs.d/elpa/magit-1.2.0/magit-wip.elc
new file mode 100644
index 0000000..29b5f26
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit-wip.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit.el b/.emacs.d/elpa/magit-1.2.0/magit.el
new file mode 100644
index 0000000..121ec9c
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit.el
@@ -0,0 +1,6001 @@
+;;; magit.el --- control Git from Emacs
+
+;; Copyright (C) 2010 Aaron Culich.
+;; Copyright (C) 2010 Alan Falloon.
+;; Copyright (C) 2008, 2010 Alex Ott.
+;; Copyright (C) 2008, 2009, 2010 Alexey Voinov.
+;; Copyright (C) 2010 Ben Walton.
+;; Copyright (C) 2010 Chris Bernard.
+;; Copyright (C) 2010 Christian Kluge.
+;; Copyright (C) 2008 Daniel Farina.
+;; Copyright (C) 2010 David Abrahams.
+;; Copyright (C) 2009 David Wallin.
+;; Copyright (C) 2009, 2010 Hannu Koivisto.
+;; Copyright (C) 2009 Ian Eure.
+;; Copyright (C) 2009 Jesse Alama.
+;; Copyright (C) 2009 John Wiegley.
+;; Copyright (C) 2010 Leo.
+;; Copyright (C) 2008, 2009 Marcin Bachry.
+;; Copyright (C) 2008, 2009 Marius Vollmer.
+;; Copyright (C) 2010 Mark Hepburn.
+;; Copyright (C) 2010 Moritz Bunkus.
+;; Copyright (C) 2010 Nathan Weizenbaum.
+;; Copyright (C) 2010 Oscar Fuentes.
+;; Copyright (C) 2009 Pavel Holejsovsky.
+;; Copyright (C) 2011-2012 Peter J Weisberg
+;; Copyright (C) 2009, 2010 Phil Jackson.
+;; Copyright (C) 2010 Philip Weaver.
+;; Copyright (C) 2010 Ramkumar Ramachandra.
+;; Copyright (C) 2010 Remco van 't Veer.
+;; Copyright (C) 2009 René Stadler.
+;; Copyright (C) 2010 Robin Green.
+;; Copyright (C) 2010 Roger Crew.
+;; Copyright (C) 2009, 2010, 2011 Rémi Vanicat.
+;; Copyright (C) 2010 Sean Bryant.
+;; Copyright (C) 2009, 2011 Steve Purcell.
+;; Copyright (C) 2010 Timo Juhani Lindfors.
+;; Copyright (C) 2010, 2011 Yann Hodique.
+;; Copyright (C) 2010 Ævar Arnfjörð Bjarmason.
+;; Copyright (C) 2010 Óscar Fuentes.
+
+;; Original Author: Marius Vollmer <marius.vollmer@nokia.com>
+;; Former Maintainer: Phil Jackson <phil@shellarchive.co.uk>
+;; Maintenance Group: https://github.com/organizations/magit/teams/53130
+;;   Currently composed of:
+;;   - Phil Jackson
+;;   - Peter J Weisberg
+;;   - Yann Hodique
+;;   - Rémi Vanicat
+;; Version: 1.2.0
+;; Keywords: tools
+
+;;
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Invoking the magit-status function will show a buffer with the
+;; status of the current git repository and its working tree.  That
+;; buffer offers key bindings for manipulating the status in simple
+;; ways.
+;;
+;; The status buffer mainly shows the difference between the working
+;; tree and the index, and the difference between the index and the
+;; current HEAD.  You can add individual hunks from the working tree
+;; to the index, and you can commit the index.
+;;
+;; See the Magit User Manual for more information.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'log-edit)
+(require 'easymenu)
+(require 'diff-mode)
+
+;; Silences byte-compiler warnings
+(eval-and-compile
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest args))))
+
+(eval-when-compile  (require 'view))
+(declare-function view-mode 'view)
+(eval-when-compile (require 'iswitchb))
+(eval-when-compile (require 'ido))
+(eval-when-compile (require 'ediff))
+
+;; Dummy to be used by the defcustoms when first loading the file.
+(eval-when (load eval)
+  (defalias 'magit-set-variable-and-refresh 'set-default))
+
+;;; Code:
+(defgroup magit nil
+  "Controlling Git from Emacs."
+  :prefix "magit-"
+  :group 'tools)
+
+(defcustom magit-git-executable "git"
+  "The name of the Git executable."
+  :group 'magit
+  :type 'string)
+
+(defcustom magit-gitk-executable (concat (file-name-directory magit-git-executable)
+                                         "gitk")
+  "The name of the Gitk executable."
+  :group 'magit
+  :type 'string)
+
+(defcustom magit-git-standard-options '("--no-pager")
+  "Standard options when running Git."
+  :group 'magit
+  :type '(repeat string))
+
+(defcustom magit-repo-dirs nil
+  "Directories containing Git repositories.
+Magit will look into these directories for Git repositories and
+offer them as choices for `magit-status'."
+  :group 'magit
+  :type '(repeat string))
+
+(defcustom magit-repo-dirs-depth 3
+  "The maximum depth to look for Git repos.
+When looking for a Git repository below the directories in `magit-repo-dirs',
+Magit will only descend this many levels deep."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-set-upstream-on-push nil
+  "Non-nil means that `magit-push' may use --set-upstream when pushing a branch.
+This only applies if the branch does not have an upstream set yet.
+Setting this to t will ask if --set-upstream should be used.
+Setting it to 'dontask will always use --set-upstream.
+Setting it to 'refuse will refuse to push unless a remote branch has already been set.
+
+--set-upstream is supported with git > 1.7.0"
+  :group 'magit
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Refuse" refuse)
+                 (const :tag "Always" dontask)))
+
+(defcustom magit-save-some-buffers t
+  "Non-nil means that \\[magit-status] will save modified buffers before running.
+Setting this to t will ask which buffers to save, setting it to 'dontask will
+save all modified buffers without asking."
+  :group 'magit
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Save without asking" dontask)))
+
+(defcustom magit-save-some-buffers-predicate
+  'magit-save-buffers-predicate-tree-only
+  "A predicate function to decide whether to save a buffer.
+
+Used by function `magit-save-some-buffers' when the variable of
+the same name is non-nil."
+
+  :group 'magit
+  :type '(radio (function-item magit-save-buffers-predicate-tree-only)
+                (function-item magit-save-buffers-predicate-all)
+                (function :tag "Other")))
+
+(defcustom magit-default-tracking-name-function
+  'magit-default-tracking-name-remote-plus-branch
+  "Specifies the function to use to generate default tracking branch names
+when doing a \\[magit-checkout].
+
+The default is magit-default-tracking-name-remote-plus-branch,
+which generates a tracking name of the form 'REMOTE-BRANCHNAME'."
+  :group 'magit
+  :type '(radio (function-item magit-default-tracking-name-remote-plus-branch)
+                (function-item magit-default-tracking-name-branch-only)
+                (function :tag "Other")))
+
+(defcustom magit-commit-all-when-nothing-staged 'ask
+  "Determines what \\[magit-log-edit] does when nothing is staged.
+Setting this to nil will make it do nothing, setting it to t will
+arrange things so that the actual commit command will use the \"--all\" option,
+setting it to 'ask will first ask for confirmation whether to do this,
+and setting it to 'ask-stage will cause all changes to be staged,
+after a confirmation."
+  :group 'magit
+  :type '(choice (const :tag "No" nil)
+                 (const :tag "Always" t)
+                 (const :tag "Ask" ask)
+                 (const :tag "Ask to stage everything" ask-stage)))
+
+(defcustom magit-commit-signoff nil
+  "Add the \"Signed-off-by:\" line when committing."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-sha1-abbrev-length 7
+  "The number of digits to show when a sha1 is displayed in abbreviated form."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-log-cutoff-length 100
+  "The maximum number of commits to show in the log and whazzup buffers."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-log-infinite-length 99999
+  "Number of log used to show as maximum for `magit-log-cutoff-length'."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-log-auto-more nil
+  "Insert more log entries automatically when moving past the last entry.
+
+Only considered when moving past the last entry with
+`magit-goto-*-section' commands."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-process-popup-time -1
+  "Popup the process buffer if a command takes longer than this many seconds."
+  :group 'magit
+  :type '(choice (const :tag "Never" -1)
+                 (const :tag "Immediately" 0)
+                 (integer :tag "After this many seconds")))
+
+(defcustom magit-revert-item-confirm t
+  "Require acknowledgment before reverting an item."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-log-edit-confirm-cancellation nil
+  "Require acknowledgment before canceling the log edit buffer."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-remote-ref-format 'branch-then-remote
+  "What format to use for autocompleting refs, in pariticular for remotes.
+
+Autocompletion is used by functions like `magit-checkout',
+`magit-interactive-rebase' and others which offer branch name
+completion.
+
+The value 'name-then-remote means remotes will be of the
+form \"name (remote)\", while the value 'remote-slash-name
+means that they'll be of the form \"remote/name\".  I.e. something that's
+listed as \"remotes/upstream/next\" by \"git branch -l -a\"
+will be \"upstream/next\"."
+  :group 'magit
+  :type '(choice (const :tag "name (remote)" branch-then-remote)
+                 (const :tag "remote/name" remote-slash-branch)))
+
+(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
+  "Connection type used for the git process.
+
+If nil, use pipes: this is usually more efficient, and works on Cygwin.
+If t, use ptys: this enables magit to prompt for passphrases when needed."
+  :group 'magit
+  :type '(choice (const :tag "pipe" nil)
+                 (const :tag "pty" t)))
+
+(defcustom magit-completing-read-function 'magit-builtin-completing-read
+  "Function to be called when requesting input from the user."
+  :group 'magit
+  :type '(radio (function-item magit-iswitchb-completing-read)
+                (function-item magit-ido-completing-read)
+                (function-item magit-builtin-completing-read)
+                (function :tag "Other")))
+
+(defcustom magit-create-branch-behaviour 'at-head
+  "Where magit will create a new branch if not supplied a branchname or ref.
+
+The value 'at-head means a new branch will be created at the tip
+of your current branch, while the value 'at-point means magit
+will try to find a valid reference at point..."
+  :group 'magit
+  :type '(choice (const :tag "at HEAD" at-head)
+                 (const :tag "at point" at-point)))
+
+(defcustom magit-status-buffer-switch-function 'pop-to-buffer
+  "Function for `magit-status' to use for switching to the status buffer.
+
+The function is given one argument, the status buffer."
+  :group 'magit
+  :type '(radio (function-item switch-to-buffer)
+                (function-item pop-to-buffer)
+                (function :tag "Other")))
+
+(defcustom magit-rewrite-inclusive t
+  "Whether magit includes the selected base commit in a rewrite operation.
+
+t means both the selected commit as well as any subsequent
+commits will be rewritten.  This is magit's default behaviour,
+equivalent to 'git rebase -i ${REV}~1'
+
+  A'---B'---C'---D'
+  ^
+
+nil means the selected commit will be literally used as 'base',
+so only subsequent commits will be rewritten.  This is consistent
+with git-rebase, equivalent to 'git rebase -i ${REV}', yet more
+cumbersome to use from the status buffer.
+
+  A---B'---C'---D'
+  ^"
+  :group 'magit
+  :type '(choice (const :tag "Always" t)
+                 (const :tag "Never" nil)
+                 (const :tag "Ask"   ask)))
+
+(defcustom magit-highlight-whitespace t
+  "Specifies where to highlight whitespace errors.
+See `magit-highlight-trailing-whitespace',
+`magit-highlight-indentation'.  The symbol t means in all diffs,
+'status means only in the status buffer, and nil means nowhere."
+  :group 'magit
+  :type '(choice (const :tag "Always" t)
+                 (const :tag "Never" nil)
+                 (const :tag "In status buffer" status))
+  :set 'magit-set-variable-and-refresh)
+
+(defcustom magit-highlight-trailing-whitespace t
+  "Highlight whitespace at the end of a line in diffs.
+Used only when `magit-highlight-whitespace' is non-nil."
+  :group 'magit
+  :type 'boolean
+  :set 'magit-set-variable-and-refresh)
+
+(defcustom magit-highlight-indentation nil
+  "Highlight the \"wrong\" indentation style.
+Used only when `magit-highlight-whitespace' is non-nil.
+
+The value is a list of cons cells.  The car is a regular
+expression, and the cdr is the value that applies to repositories
+whose directory matches the regular expression.  If more than one
+item matches, then the *last* item in the list applies.  So, the
+default value should come first in the list.
+
+If the value is `tabs', highlight indentation with tabs.  If the
+value is an integer, highlight indentation with at least that
+many spaces.  Otherwise, highlight neither."
+  :group 'magit
+  :type `(repeat (cons (string :tag "Directory regexp")
+                       (choice (const :tag "Tabs" tabs)
+                               (integer :tag "Spaces" :value ,tab-width)
+                               (const :tag "Neither" nil))))
+  :set 'magit-set-variable-and-refresh)
+
+(defcustom magit-diff-refine-hunk nil
+  "Show fine (word-granularity) differences within diff hunks.
+
+There are three possible settings:
+
+  nil means to never show fine differences
+
+  t means to only show fine differences for the currently
+  selected diff hunk
+
+  `all' means to always show fine differences for all displayed diff hunks"
+  :group 'magit
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Selected only" t)
+                 (const :tag "All" all))
+  :set 'magit-set-variable-and-refresh)
+
+(defvar magit-current-indentation nil
+  "Indentation highlight used in the current buffer.
+This is calculated from `magit-highlight-indentation'.")
+(make-variable-buffer-local 'magit-current-indentation)
+
+(defgroup magit-faces nil
+  "Customize the appearance of Magit."
+  :prefix "magit-"
+  :group 'faces
+  :group 'magit)
+
+(defface magit-header
+  '((t :inherit header-line))
+  "Face for generic header lines.
+
+Many Magit faces inherit from this one by default."
+  :group 'magit-faces)
+
+(defface magit-section-title
+  '((t :inherit magit-header))
+  "Face for section titles."
+  :group 'magit-faces)
+
+(defface magit-branch
+  '((t :inherit magit-header))
+  "Face for the current branch."
+  :group 'magit-faces)
+
+(defface magit-diff-file-header
+  '((t :inherit diff-file-header))
+  "Face for diff file header lines."
+  :group 'magit-faces)
+
+(defface magit-diff-hunk-header
+  '((t :inherit diff-hunk-header))
+  "Face for diff hunk header lines."
+  :group 'magit-faces)
+
+(defface magit-diff-add
+  '((t :inherit diff-added))
+  "Face for lines in a diff that have been added."
+  :group 'magit-faces)
+
+(defface magit-diff-none
+  '((t :inherit diff-context))
+  "Face for lines in a diff that are unchanged."
+  :group 'magit-faces)
+
+(defface magit-diff-del
+  '((t :inherit diff-removed))
+  "Face for lines in a diff that have been deleted."
+  :group 'magit-faces)
+
+(defface magit-log-graph
+  '((((class color) (background light))
+     :foreground "grey11")
+    (((class color) (background dark))
+     :foreground "grey80"))
+  "Face for the graph element of the log output."
+  :group 'magit-faces)
+
+(defface magit-log-sha1
+  '((((class color) (background light))
+     :foreground "firebrick")
+    (((class color) (background dark))
+     :foreground "tomato"))
+  "Face for the sha1 element of the log output."
+  :group 'magit-faces)
+
+(defface magit-log-message
+  '((t))
+  "Face for the message element of the log output."
+  :group 'magit-faces)
+
+(defface magit-item-highlight
+  '((t :inherit highlight))
+  "Face for highlighting the current item."
+  :group 'magit-faces)
+
+(defface magit-item-mark
+  '((t :inherit secondary-selection))
+  "Face for highlighting marked item."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-bisect-good
+  '((((class color) (background light))
+     :box t
+     :background "light green"
+     :foreground "dark olive green")
+    (((class color) (background dark))
+     :box t
+     :background "light green"
+     :foreground "dark olive green"))
+  "Face for good bisect refs."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-bisect-bad
+  '((((class color) (background light))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4")
+    (((class color) (background dark))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4"))
+  "Face for bad bisect refs."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-remote
+  '((((class color) (background light))
+     :box t
+     :background "Grey85"
+     :foreground "OliveDrab4")
+    (((class color) (background dark))
+     :box t
+     :background "Grey11"
+     :foreground "DarkSeaGreen2"))
+  "Face for remote branch head labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-tags
+  '((((class color) (background light))
+     :box t
+     :background "LemonChiffon1"
+     :foreground "goldenrod4")
+    (((class color) (background dark))
+     :box t
+     :background "LemonChiffon1"
+     :foreground "goldenrod4"))
+  "Face for tag labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-patches
+  '((((class color) (background light))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4")
+    (((class color) (background dark))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4"))
+  "Face for Stacked Git patches."
+  :group 'magit-faces)
+
+(defface magit-whitespace-warning-face
+  '((t :inherit trailing-whitespace))
+  "Face for highlighting whitespace errors in Magit diffs."
+  :group 'magit-faces)
+
+(defvar magit-custom-options '()
+  "List of custom options to pass to Git.
+Do not customize this (used in the `magit-key-mode' implementation).")
+
+(defvar magit-read-rev-history nil
+  "The history of inputs to `magit-read-rev'.")
+
+(defvar magit-buffer-internal nil
+  "Track associated *magit* buffers.
+Do not customize this (used in the `magit-log-edit-mode' implementation
+to switch back to the *magit* buffer associated with a given commit
+operation after commit).")
+
+(defvar magit-back-navigation-history nil
+  "History items that will be visited by successively going \"back\".")
+(make-variable-buffer-local 'magit-back-navigation-history)
+(put 'magit-back-navigation-history 'permanent-local t)
+
+(defvar magit-forward-navigation-history nil
+  "History items that will be visited by successively going \"forward\".")
+(make-variable-buffer-local 'magit-forward-navigation-history)
+(put 'magit-forward-navigation-history 'permanent-local t)
+
+(defvar magit-omit-untracked-dir-contents nil
+  "When non-nil magit will only list an untracked directory, not its contents.")
+
+(defvar magit-tmp-buffer-name " *magit-tmp*")
+
+(defface magit-log-head-label-local
+  '((((class color) (background light))
+     :box t
+     :background "Grey85"
+     :foreground "LightSkyBlue4")
+    (((class color) (background dark))
+     :box t
+     :background "Grey13"
+     :foreground "LightSkyBlue1"))
+  "Face for local branch head labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-default
+  '((((class color) (background light))
+     :box t
+     :background "Grey50")
+    (((class color) (background dark))
+     :box t
+     :background "Grey50"))
+  "Face for unknown ref labels shown in log buffer."
+  :group 'magit-faces)
+
+(defvar magit-mode-map
+  (let ((map (make-keymap)))
+    (suppress-keymap map t)
+    (define-key map (kbd "n") 'magit-goto-next-section)
+    (define-key map (kbd "p") 'magit-goto-previous-section)
+    (define-key map (kbd "^") 'magit-goto-parent-section)
+    (define-key map (kbd "M-n") 'magit-goto-next-sibling-section)
+    (define-key map (kbd "M-p") 'magit-goto-previous-sibling-section)
+    (define-key map (kbd "TAB") 'magit-toggle-section)
+    (define-key map (kbd "<backtab>") 'magit-expand-collapse-section)
+    (define-key map (kbd "1") 'magit-show-level-1)
+    (define-key map (kbd "2") 'magit-show-level-2)
+    (define-key map (kbd "3") 'magit-show-level-3)
+    (define-key map (kbd "4") 'magit-show-level-4)
+    (define-key map (kbd "M-1") 'magit-show-level-1-all)
+    (define-key map (kbd "M-2") 'magit-show-level-2-all)
+    (define-key map (kbd "M-3") 'magit-show-level-3-all)
+    (define-key map (kbd "M-4") 'magit-show-level-4-all)
+    (define-key map (kbd "M-h") 'magit-show-only-files)
+    (define-key map (kbd "M-H") 'magit-show-only-files-all)
+    (define-key map (kbd "M-s") 'magit-show-level-4)
+    (define-key map (kbd "M-S") 'magit-show-level-4-all)
+    (define-key map (kbd "g") 'magit-refresh)
+    (define-key map (kbd "G") 'magit-refresh-all)
+    (define-key map (kbd "?") 'magit-describe-item)
+    (define-key map (kbd "!") 'magit-key-mode-popup-running)
+    (define-key map (kbd ":") 'magit-git-command)
+    (define-key map (kbd "C-x 4 a") 'magit-add-change-log-entry-other-window)
+    (define-key map (kbd "L") 'magit-add-change-log-entry-no-option)
+    (define-key map (kbd "RET") 'magit-visit-item)
+    (define-key map (kbd "SPC") 'magit-show-item-or-scroll-up)
+    (define-key map (kbd "DEL") 'magit-show-item-or-scroll-down)
+    (define-key map (kbd "C-w") 'magit-copy-item-as-kill)
+    (define-key map (kbd "R") 'magit-rebase-step)
+    (define-key map (kbd "t") 'magit-key-mode-popup-tagging)
+    (define-key map (kbd "r") 'magit-key-mode-popup-rewriting)
+    (define-key map (kbd "P") 'magit-key-mode-popup-pushing)
+    (define-key map (kbd "f") 'magit-key-mode-popup-fetching)
+    (define-key map (kbd "b") 'magit-key-mode-popup-branching)
+    (define-key map (kbd "M") 'magit-key-mode-popup-remoting)
+    (define-key map (kbd "B") 'magit-key-mode-popup-bisecting)
+    (define-key map (kbd "F") 'magit-key-mode-popup-pulling)
+    (define-key map (kbd "l") 'magit-key-mode-popup-logging)
+    (define-key map (kbd "$") 'magit-display-process)
+    (define-key map (kbd "c") 'magit-log-edit)
+    (define-key map (kbd "E") 'magit-interactive-rebase)
+    (define-key map (kbd "e") 'magit-ediff)
+    (define-key map (kbd "w") 'magit-wazzup)
+    (define-key map (kbd "q") 'magit-quit-window)
+    (define-key map (kbd "m") 'magit-key-mode-popup-merging)
+    (define-key map (kbd "x") 'magit-reset-head)
+    (define-key map (kbd "v") 'magit-revert-item)
+    (define-key map (kbd "a") 'magit-apply-item)
+    (define-key map (kbd "A") 'magit-cherry-pick-item)
+    (define-key map (kbd "d") 'magit-diff-working-tree)
+    (define-key map (kbd "D") 'magit-diff)
+    (define-key map (kbd "-") 'magit-diff-smaller-hunks)
+    (define-key map (kbd "+") 'magit-diff-larger-hunks)
+    (define-key map (kbd "0") 'magit-diff-default-hunks)
+    (define-key map (kbd "h") 'magit-toggle-diff-refine-hunk)
+    map))
+
+(defvar magit-commit-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-b") 'magit-show-commit-backward)
+    (define-key map (kbd "C-c C-f") 'magit-show-commit-forward)
+    map))
+
+(defvar magit-status-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "s") 'magit-stage-item)
+    (define-key map (kbd "S") 'magit-stage-all)
+    (define-key map (kbd "u") 'magit-unstage-item)
+    (define-key map (kbd "U") 'magit-unstage-all)
+    (define-key map (kbd "i") 'magit-ignore-item)
+    (define-key map (kbd "I") 'magit-ignore-item-locally)
+    (define-key map (kbd ".") 'magit-mark-item)
+    (define-key map (kbd "=") 'magit-diff-with-mark)
+    (define-key map (kbd "k") 'magit-discard-item)
+    (define-key map (kbd "C") 'magit-add-log)
+    (define-key map (kbd "X") 'magit-reset-working-tree)
+    (define-key map (kbd "z") 'magit-key-mode-popup-stashing)
+    map))
+
+(eval-after-load 'dired-x
+  '(define-key magit-status-mode-map [remap dired-jump] 'magit-dired-jump))
+
+(defvar magit-log-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd ".") 'magit-mark-item)
+    (define-key map (kbd "=") 'magit-diff-with-mark)
+    (define-key map (kbd "e") 'magit-log-show-more-entries)
+    map))
+
+(defvar magit-wazzup-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd ".") 'magit-mark-item)
+    (define-key map (kbd "=") 'magit-diff-with-mark)
+    (define-key map (kbd "i") 'magit-ignore-item)
+    map))
+
+(defvar magit-branch-manager-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "c") 'magit-create-branch)
+    (define-key map (kbd "a") 'magit-add-remote)
+    (define-key map (kbd "r") 'magit-move-item)
+    (define-key map (kbd "k") 'magit-discard-item)
+    (define-key map (kbd "T") 'magit-change-what-branch-tracks)
+    map))
+
+(defvar magit-bug-report-url
+  "http://github.com/magit/magit/issues")
+
+(defconst magit-version "1.2.0"
+  "The version of Magit that you're using.")
+
+(defun magit-bug-report (str)
+  "Asks the user to submit a bug report about the error described in STR."
+;; XXX - should propose more information to be included.
+  (message (concat
+            "Unknown error: %s\n"
+            "Please, with as much information as possible, file a bug at\n"
+            "%s\n"
+            "You are using Magit version %s.")
+           str magit-bug-report-url magit-version))
+
+(defun magit-buffer-switch (buf)
+  (if (string-match "magit" (buffer-name))
+      (switch-to-buffer buf)
+    (pop-to-buffer buf)))
+
+;;; Macros
+
+(defmacro magit-with-refresh (&rest body)
+  (declare (indent 0))
+  `(magit-refresh-wrapper (lambda () ,@body)))
+
+;;; Git features
+
+(defvar magit-have-graph 'unset)
+(defvar magit-have-decorate 'unset)
+(defvar magit-have-abbrev 'unset)
+(make-variable-buffer-local 'magit-have-graph)
+(put 'magit-have-graph 'permanent-local t)
+(make-variable-buffer-local 'magit-have-decorate)
+(put 'magit-have-decorate 'permanent-local t)
+(make-variable-buffer-local 'magit-have-abbrev)
+(put 'magit-have-abbrev 'permanent-local t)
+
+(defun magit-configure-have-graph ()
+  (if (eq magit-have-graph 'unset)
+      (let ((res (magit-git-exit-code "log" "--graph" "--max-count=0")))
+        (setq magit-have-graph (eq res 0)))))
+
+(defun magit-configure-have-decorate ()
+  (if (eq magit-have-decorate 'unset)
+      (let ((res (magit-git-exit-code "log" "--decorate=full" "--max-count=0")))
+        (setq magit-have-decorate (eq res 0)))))
+
+(defun magit-configure-have-abbrev ()
+  (if (eq magit-have-abbrev 'unset)
+      (let ((res (magit-git-exit-code "log" "--no-abbrev-commit" "--max-count=0")))
+        (setq magit-have-abbrev (eq res 0)))))
+
+;;; Compatibilities
+
+(eval-and-compile
+  (defun magit-max-args-internal (function)
+    "Returns the maximum number of arguments accepted by FUNCTION."
+    (if (symbolp function)
+        (setq function (symbol-function function)))
+    (if (subrp function)
+        (let ((max (cdr (subr-arity function))))
+          (if (eq 'many max)
+              most-positive-fixnum
+            max))
+      (if (eq 'macro (car-safe function))
+          (setq function (cdr function)))
+      (let ((arglist (if (byte-code-function-p function)
+                         (aref function 0)
+                       (second function))))
+        (if (memq '&rest arglist)
+            most-positive-fixnum
+          (length (remq '&optional arglist))))))
+
+  (if (functionp 'start-file-process)
+      (defalias 'magit-start-process 'start-file-process)
+    (defalias 'magit-start-process 'start-process))
+
+  (unless (fboundp 'string-match-p)
+    (defun string-match-p (regexp string &optional start)
+      "Same as `string-match' except this function does not
+change the match data."
+      (let ((inhibit-changing-match-data t))
+        (string-match regexp string start))))
+
+  (if (fboundp 'with-silent-modifications)
+      (defalias 'magit-with-silent-modifications 'with-silent-modifications)
+    (defmacro magit-with-silent-modifications (&rest body)
+      "Execute body without changing `buffer-modified-p'. Also, do not
+record undo information."
+      `(set-buffer-modified-p
+        (prog1 (buffer-modified-p)
+          (let ((buffer-undo-list t)
+                before-change-functions
+                after-change-functions)
+            ,@body)))))
+
+  (if (>= (magit-max-args-internal 'delete-directory) 2)
+      (defalias 'magit-delete-directory 'delete-directory)
+    (defun magit-delete-directory (directory &optional recursive)
+      "Deletes a directory named DIRECTORY.  If RECURSIVE is non-nil,
+recursively delete all of DIRECTORY's contents as well.
+
+Does not follow symlinks."
+      (if (or (file-symlink-p directory)
+              (not (file-directory-p directory)))
+          (delete-file directory)
+        (if recursive
+            ;; `directory-files-no-dot-files-regex' borrowed from Emacs 23
+            (dolist (file (directory-files directory 'full "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"))
+              (magit-delete-directory file recursive)))
+        (delete-directory directory)))))
+
+;;; Utilities
+
+(defun magit-set-variable-and-refresh (symbol value)
+  "Set SYMBOL to VALUE and call `magit-refresh-all'"
+  (set-default symbol value)
+  (magit-refresh-all))
+
+(defun magit-iswitchb-completing-read (prompt choices &optional predicate require-match
+                                              initial-input hist def)
+  "iswitchb-based completing-read almost-replacement."
+  (require 'iswitchb)
+  (let ((iswitchb-make-buflist-hook
+         (lambda ()
+           (setq iswitchb-temp-buflist (if (consp (first choices))
+                                           (mapcar #'car choices)
+                                         choices)))))
+    (iswitchb-read-buffer prompt (or initial-input def) require-match)))
+
+(defun magit-ido-completing-read (prompt choices &optional predicate require-match initial-input hist def)
+  "ido-based completing-read almost-replacement."
+  (require 'ido)
+  (let ((selected (ido-completing-read prompt (if (consp (first choices))
+                                                  (mapcar #'car choices)
+                                                choices)
+                                       predicate require-match initial-input hist def)))
+    (if (consp (first choices))
+        (or (cdr (assoc selected choices))
+            selected)
+      selected)))
+
+(defun magit-builtin-completing-read (prompt choices &optional predicate require-match
+                                             initial-input hist def)
+  "Magit wrapper for standard `completing-read' function."
+  (completing-read (if (and def (> (length prompt) 2)
+                            (string-equal ": " (substring prompt -2)))
+                       (format "%s (default %s): " (substring prompt 0 -2) def)
+                     prompt)
+                   choices predicate require-match initial-input hist def))
+
+(defun magit-completing-read (prompt choices &optional predicate require-match
+                                     initial-input hist def)
+  (funcall magit-completing-read-function prompt choices predicate require-match
+           initial-input hist def))
+
+(defun magit-use-region-p ()
+  (if (fboundp 'use-region-p)
+      (use-region-p)
+    (and transient-mark-mode mark-active)))
+
+(defun magit-goto-line (line)
+  "Like `goto-line' but doesn't set the mark."
+  (save-restriction
+    (widen)
+    (goto-char 1)
+    (forward-line (1- line))))
+
+(defun magit-trim-line (str)
+  (if (string= str "")
+      nil
+    (if (equal (elt str (- (length str) 1)) ?\n)
+        (substring str 0 (- (length str) 1))
+      str)))
+
+(defun magit-split-lines (str)
+  (if (string= str "")
+      nil
+    (let ((lines (nreverse (split-string str "\n"))))
+      (if (string= (car lines) "")
+          (setq lines (cdr lines)))
+      (nreverse lines))))
+
+(defun magit-git-insert (args)
+  (insert (magit-git-output args)))
+
+(defun magit-git-output (args)
+  (magit-cmd-output magit-git-executable (append magit-git-standard-options args)))
+
+(defun magit-cmd-insert (cmd args)
+  (insert (magit-cmd-output cmd args)))
+
+(defun magit-cmd-output (cmd args)
+  (let ((cmd-output (with-output-to-string
+                      (with-current-buffer standard-output
+                        (apply #'process-file
+                               cmd
+                               nil (list t nil) nil
+                               args)))))
+    (replace-regexp-in-string "\e\\[.*?m" "" cmd-output)))
+
+(defun magit-git-string (&rest args)
+  (magit-trim-line (magit-git-output args)))
+
+(defun magit-git-lines (&rest args)
+  (magit-split-lines (magit-git-output args)))
+
+(defun magit-git-exit-code (&rest args)
+  (apply #'process-file magit-git-executable nil nil nil
+         (append magit-git-standard-options args)))
+
+(defun magit-file-lines (file)
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (let ((rev (nreverse (split-string (buffer-string) "\n"))))
+        (nreverse (if (equal (car rev) "")
+                      (cdr rev)
+                    rev))))))
+
+(defun magit-write-file-lines (file lines)
+  (with-temp-buffer
+    (dolist (l lines)
+      (insert l "\n"))
+    (write-file file)))
+
+(defun magit-get (&rest keys)
+  "Return the value of Git config entry specified by KEYS."
+  (magit-git-string "config" (mapconcat 'identity keys ".")))
+
+(defun magit-get-all (&rest keys)
+  "Return all values of the Git config entry specified by KEYS."
+  (magit-git-lines "config" "--get-all" (mapconcat 'identity keys ".")))
+
+(defun magit-get-boolean (&rest keys)
+  "Return the boolean value of Git config entry specified by KEYS."
+  (equal (magit-git-string "config" "--bool" (mapconcat 'identity keys "."))
+         "true"))
+
+(defun magit-set (val &rest keys)
+  "Set Git config settings specified by KEYS to VAL."
+  (if val
+      (magit-git-string "config" (mapconcat 'identity keys ".") val)
+    (magit-git-string "config" "--unset" (mapconcat 'identity keys "."))))
+
+(defun magit-remove-conflicts (alist)
+  (let ((dict (make-hash-table :test 'equal))
+        (result nil))
+    (dolist (a alist)
+      (puthash (car a) (cons (cdr a) (gethash (car a) dict))
+               dict))
+    (maphash (lambda (key value)
+               (if (= (length value) 1)
+                   (push (cons key (car value)) result)
+                 (let ((sub (magit-remove-conflicts
+                             (mapcar (lambda (entry)
+                                       (let ((dir (directory-file-name
+                                                   (substring entry 0 (- (length key))))))
+                                         (cons (concat (file-name-nondirectory dir) "/" key)
+                                               entry)))
+                                     value))))
+                   (setq result (append result sub)))))
+             dict)
+    result))
+
+(defun magit-git-repo-p (dir)
+  (file-exists-p (expand-file-name ".git" dir)))
+
+(defun magit-git-dir ()
+  "Returns the .git directory for the current repository."
+  (concat (expand-file-name (magit-git-string "rev-parse" "--git-dir")) "/"))
+
+(defun magit-no-commit-p ()
+  "Return non-nil if there is no commit in the current git repository."
+  (not (magit-git-string
+        "rev-list" "HEAD" "--max-count=1")))
+
+(defun magit-list-repos* (dir level)
+  (if (magit-git-repo-p dir)
+      (list dir)
+    (apply #'append
+           (mapcar (lambda (entry)
+                     (unless (or (string= (substring entry -3) "/..")
+                                 (string= (substring entry -2) "/."))
+                       (magit-list-repos* entry (+ level 1))))
+                   (and (file-directory-p dir)
+                        (< level magit-repo-dirs-depth)
+                        (directory-files dir t nil t))))))
+
+(defun magit-list-repos (dirs)
+  (magit-remove-conflicts
+   (apply #'append
+          (mapcar (lambda (dir)
+                    (mapcar #'(lambda (repo)
+                                (cons (file-name-nondirectory repo)
+                                      repo))
+                            (magit-list-repos* dir 0)))
+                  dirs))))
+
+(defun magit-get-top-dir (cwd)
+  (let ((cwd (expand-file-name (file-truename cwd))))
+    (when (file-directory-p cwd)
+      (let* ((default-directory (file-name-as-directory cwd))
+             (cdup (magit-git-string "rev-parse" "--show-cdup")))
+        (when cdup
+          (file-name-as-directory (expand-file-name cdup cwd)))))))
+
+(defun magit-get-ref (ref)
+  (magit-git-string "symbolic-ref" "-q" ref))
+
+(defun magit-get-current-branch ()
+  (let* ((head (magit-get-ref "HEAD"))
+         (pos (and head (string-match "^refs/heads/" head))))
+    (if pos
+        (substring head 11)
+      nil)))
+
+(defun magit-get-remote (branch)
+  "Return the name of the remote for BRANCH.
+If branch is nil or it has no remote, but a remote named
+\"origin\" exists, return that. Otherwise, return nil."
+  (let ((remote (or (and branch (magit-get "branch" branch "remote"))
+                    (and (magit-get "remote" "origin" "url") "origin"))))
+    (if (string= remote "") nil remote)))
+
+(defun magit-get-current-remote ()
+  "Return the name of the remote for the current branch.
+If there is no current branch, or no remote for that branch,
+but a remote named \"origin\" is configured, return that.
+Otherwise, return nil."
+  (magit-get-remote (magit-get-current-branch)))
+
+(defun magit-ref-exists-p (ref)
+  (= (magit-git-exit-code "show-ref" "--verify" ref) 0))
+
+(defun magit-read-top-dir (dir)
+  "Ask the user for a Git repository.  The choices offered by
+auto-completion will be the repositories under `magit-repo-dirs'.
+If `magit-repo-dirs' is nil or DIR is non-nill, then
+autocompletion will offer directory names."
+  (if (and (not dir) magit-repo-dirs)
+      (let* ((repos (magit-list-repos magit-repo-dirs))
+             (reply (magit-completing-read "Git repository: " repos)))
+        (file-name-as-directory
+         (or (cdr (assoc reply repos))
+             (if (file-directory-p reply)
+                 (expand-file-name reply)
+               (error "Not a repository or a directory: %s" reply)))))
+    (file-name-as-directory
+     (read-directory-name "Git repository: "
+                          (or (magit-get-top-dir default-directory)
+                              default-directory)))))
+
+(defun magit-rev-parse (ref)
+  "Return the SHA hash for REF."
+  (magit-git-string "rev-parse" ref))
+
+(defun magit-ref-ambiguous-p (ref)
+  "Return whether or not REF is ambiguous."
+  ;; If REF is ambiguous, rev-parse just prints errors,
+  ;; so magit-git-string returns nil.
+  (not (magit-git-string "rev-parse" "--abbrev-ref" ref)))
+
+(defun magit-name-rev (rev &optional no-trim)
+  "Return a human-readable name for REV.
+Unlike git name-rev, this will remove tags/ and remotes/ prefixes
+if that can be done unambiguously (unless optional arg NO-TRIM is
+non-nil).  In addition, it will filter out revs involving HEAD."
+  (when rev
+    (let ((name (magit-git-string "name-rev" "--no-undefined" "--name-only" rev)))
+      ;; There doesn't seem to be a way of filtering HEAD out from name-rev,
+      ;; so we have to do it manually.
+      ;; HEAD-based names are too transient to allow.
+      (when (and (stringp name)
+                 (string-match "^\\(.*\\<HEAD\\)\\([~^].*\\|$\\)" name))
+        (let ((head-ref (match-string 1 name))
+              (modifier (match-string 2 name)))
+          ;; Sometimes when name-rev gives a HEAD-based name,
+          ;; rev-parse will give an actual branch or remote name.
+          (setq name (concat (magit-git-string "rev-parse" "--abbrev-ref" head-ref)
+                             modifier))
+          ;; If rev-parse doesn't give us what we want, just use the SHA.
+          (when (or (null name) (string-match-p "\\<HEAD\\>" name))
+            (setq name (magit-rev-parse rev)))))
+      (setq rev (or name rev))
+      (when (string-match "^\\(?:tags\\|remotes\\)/\\(.*\\)" rev)
+        (let ((plain-name (match-string 1 rev)))
+          (unless (or no-trim (magit-ref-ambiguous-p plain-name))
+            (setq rev plain-name))))
+      rev)))
+
+(defun magit-highlight-line-whitespace ()
+  (when (and magit-highlight-whitespace
+             (or (derived-mode-p 'magit-status-mode)
+                 (not (eq magit-highlight-whitespace 'status))))
+    (if (and magit-highlight-trailing-whitespace
+             (looking-at "^[-+].*?\\([ \t]+\\)$"))
+        (overlay-put (make-overlay (match-beginning 1) (match-end 1))
+                     'face 'magit-whitespace-warning-face))
+    (if (or (and (eq magit-current-indentation 'tabs)
+                 (looking-at "^[-+]\\( *\t[ \t]*\\)"))
+            (and (integerp magit-current-indentation)
+                 (looking-at (format "^[-+]\\([ \t]* \\{%s,\\}[ \t]*\\)"
+                                     magit-current-indentation))))
+        (overlay-put (make-overlay (match-beginning 1) (match-end 1))
+                     'face 'magit-whitespace-warning-face))))
+
+(defun magit-put-line-property (prop val)
+  (put-text-property (line-beginning-position) (line-beginning-position 2)
+                     prop val))
+
+(defun magit-format-commit (commit format)
+  (magit-git-string "log" "--max-count=1"
+                    (concat "--pretty=format:" format)
+                    commit))
+
+(defun magit-current-line ()
+  (buffer-substring-no-properties (line-beginning-position)
+                                  (line-end-position)))
+
+(defun magit-insert-region (beg end buf)
+  (let ((text (buffer-substring-no-properties beg end)))
+    (with-current-buffer buf
+      (insert text))))
+
+(defun magit-insert-current-line (buf)
+  (let ((text (buffer-substring-no-properties
+               (line-beginning-position) (line-beginning-position 2))))
+    (with-current-buffer buf
+      (insert text))))
+
+(defun magit-file-uptodate-p (file)
+  (eq (magit-git-exit-code "diff" "--quiet" "--" file) 0))
+
+(defun magit-anything-staged-p ()
+  (not (eq (magit-git-exit-code "diff" "--quiet" "--cached") 0)))
+
+(defun magit-everything-clean-p ()
+  (and (not (magit-anything-staged-p))
+       (eq (magit-git-exit-code "diff" "--quiet") 0)))
+
+(defun magit-commit-parents (commit)
+  (cdr (split-string (magit-git-string "rev-list" "-1" "--parents" commit))))
+
+;; XXX - let the user choose the parent
+
+(defun magit-choose-parent-id (commit op)
+  (let* ((parents (magit-commit-parents commit)))
+    (if (> (length parents) 1)
+        (error "Can't %s merge commits" op)
+      nil)))
+
+;;; Revisions and ranges
+
+(defvar magit-current-range nil
+  "The range described by the current buffer.
+This is only non-nil in diff and log buffers.
+
+This has three possible (non-nil) forms.  If it's a string REF or
+a singleton list (REF), then the range is from REF to the current
+working directory state (or HEAD in a log buffer).  If it's a
+pair (START . END), then the range is START..END.")
+(make-variable-buffer-local 'magit-current-range)
+
+(defun magit-list-interesting-refs (&optional uninteresting)
+  "Return interesting references as given by `git show-ref'.
+Removes references matching UNINTERESTING from the
+results. UNINTERESTING can be either a function taking a single
+argument or a list of strings used as regexps."
+  (let ((refs ()))
+    (dolist (line (magit-git-lines "show-ref"))
+      (if (string-match "[^ ]+ +\\(.*\\)" line)
+          (let ((ref (match-string 1 line)))
+            (cond ((and (functionp uninteresting)
+                        (funcall uninteresting ref)))
+                  ((and (not (functionp uninteresting))
+                        (loop for i in uninteresting thereis (string-match i ref))))
+                  (t
+                   (let ((fmt-ref (magit-format-ref ref)))
+                     (when fmt-ref
+                       (push (cons fmt-ref
+                                   (replace-regexp-in-string "^refs/heads/"
+                                                             "" ref))
+                             refs))))))))
+    (nreverse refs)))
+
+(defun magit-format-ref (ref)
+  "Convert fully-specified ref REF into its displayable form
+according to `magit-remote-ref-format'"
+  (cond
+   ((null ref)
+    nil)
+   ((string-match "refs/heads/\\(.*\\)" ref)
+    (match-string 1 ref))
+   ((string-match "refs/tags/\\(.*\\)" ref)
+    (format (if (eq magit-remote-ref-format 'branch-then-remote)
+                "%s (tag)"
+              "%s")
+            (match-string 1 ref)))
+   ((string-match "refs/remotes/\\([^/]+\\)/\\(.+\\)" ref)
+    (if (eq magit-remote-ref-format 'branch-then-remote)
+        (format "%s (%s)"
+                (match-string 2 ref)
+                (match-string 1 ref))
+      (format "%s/%s"
+              (match-string 1 ref)
+              (match-string 2 ref))))))
+
+(defun magit-tree-contents (treeish)
+  "Returns a list of all files under TREEISH.  TREEISH can be a tree,
+a commit, or any reference to one of those."
+  (let ((return-value nil))
+    (with-temp-buffer
+      (magit-git-insert (list "ls-tree" "-r" treeish))
+      (if (eql 0 (buffer-size))
+          (error "%s is not a commit or tree." treeish))
+      (goto-char (point-min))
+      (while (search-forward-regexp "\t\\(.*\\)" nil 'noerror)
+        (push (match-string 1) return-value)))
+    return-value))
+
+(defvar magit-uninteresting-refs '("refs/remotes/\\([^/]+\\)/HEAD$" "refs/stash"))
+
+(defun magit-read-file-from-rev (revision)
+  (magit-completing-read (format "Retrieve file from %s: " revision)
+                         (magit-tree-contents revision)
+                         nil
+                         'require-match
+                         nil
+                         'magit-read-file-hist
+                         (if buffer-file-name
+                             (let ((topdir-length (length (magit-get-top-dir default-directory))))
+                               (substring (buffer-file-name) topdir-length)))))
+
+(defun magit-read-rev (prompt &optional default uninteresting)
+  (let* ((interesting-refs (magit-list-interesting-refs
+                            (or uninteresting magit-uninteresting-refs)))
+         (reply (magit-completing-read (concat prompt ": ") interesting-refs
+                                       nil nil nil 'magit-read-rev-history default))
+         (rev (or (cdr (assoc reply interesting-refs)) reply)))
+    (if (string= rev "")
+        nil
+      rev)))
+
+(defun magit-read-rev-range (op &optional def-beg def-end)
+  (let ((beg (magit-read-rev (format "%s start" op)
+                             def-beg)))
+    (if (not beg)
+        nil
+      (save-match-data
+        (if (string-match "^\\(.+\\)\\.\\.\\(.+\\)$" beg)
+            (cons (match-string 1 beg) (match-string 2 beg))
+          (let ((end (magit-read-rev (format "%s end" op) def-end)))
+            (cons beg end)))))))
+
+(defun magit-rev-to-git (rev)
+  (or rev
+      (error "No revision specified"))
+  (if (string= rev ".")
+      (magit-marked-commit)
+    rev))
+
+(defun magit-rev-range-to-git (range)
+  (or range
+      (error "No revision range specified"))
+  (if (stringp range)
+      range
+    (if (cdr range)
+        (format "%s..%s"
+                (magit-rev-to-git (car range))
+                (magit-rev-to-git (cdr range)))
+      (format "%s" (magit-rev-to-git (car range))))))
+
+(defun magit-rev-describe (rev)
+  (or rev
+      (error "No revision specified"))
+  (if (string= rev ".")
+      "mark"
+    (magit-name-rev rev)))
+
+(defun magit-rev-range-describe (range things)
+  (or range
+      (error "No revision range specified"))
+  (if (stringp range)
+      (format "%s in %s" things range)
+    (if (cdr range)
+        (format "%s from %s to %s" things
+                (magit-rev-describe (car range))
+                (magit-rev-describe (cdr range)))
+      (format "%s at %s" things (magit-rev-describe (car range))))))
+
+(defun magit-default-rev (&optional no-trim)
+  (or (magit-name-rev (magit-commit-at-point t) no-trim)
+      (let ((branch (magit-guess-branch)))
+        (if branch
+            (if (string-match "^refs/\\(.*\\)" branch)
+                (match-string 1 branch)
+              branch)))))
+
+(defun magit-read-remote (&optional prompt def)
+  "Read the name of a remote.
+PROMPT is used as the prompt, and defaults to \"Remote\".
+DEF is the default value."
+  (let* ((prompt (or prompt "Remote"))
+         (def (or def (magit-guess-remote)))
+         (remotes (magit-git-lines "remote"))
+
+         (reply (magit-completing-read (concat prompt ": ") remotes
+                                       nil nil nil nil def)))
+    (if (string= reply "") nil reply)))
+
+(defun magit-read-remote-branch (remote &optional prompt default)
+  (let* ((prompt (or prompt (format "Remote branch (in %s)" remote)))
+         (branches (delete nil
+                           (mapcar
+                            (lambda (b)
+                              (and (not (string-match " -> " b))
+                                   (string-match (format "^ *%s/\\(.*\\)$"
+                                                         (regexp-quote remote)) b)
+                                   (match-string 1 b)))
+                            (magit-git-lines "branch" "-r"))))
+         (reply (magit-completing-read (concat prompt ": ") branches
+                                       nil nil nil nil default)))
+    (if (string= reply "") nil reply)))
+
+;;; Sections
+
+;; A buffer in magit-mode is organized into hierarchical sections.
+;; These sections are used for navigation and for hiding parts of the
+;; buffer.
+;;
+;; Most sections also represent the objects that Magit works with,
+;; such as files, diffs, hunks, commits, etc.  The 'type' of a section
+;; identifies what kind of object it represents (if any), and the
+;; parent and grand-parent, etc provide the context.
+
+(defstruct magit-section
+  parent title beginning end children hidden type info
+  needs-refresh-on-show)
+
+(defvar magit-top-section nil
+  "The top section of the current buffer.")
+(make-variable-buffer-local 'magit-top-section)
+(put 'magit-top-section 'permanent-local t)
+
+(defvar magit-old-top-section nil)
+
+(defvar magit-section-hidden-default nil)
+
+(defun magit-new-section (title type)
+  "Create a new section with title TITLE and type TYPE in current buffer.
+
+If not `magit-top-section' exist, the new section will be the new top-section
+otherwise, the new-section will be a child of the current top-section.
+
+If TYPE is nil, the section won't be highlighted."
+  (let* ((s (make-magit-section :parent magit-top-section
+                                :title title
+                                :type type
+                                :hidden magit-section-hidden-default))
+         (old (and magit-old-top-section
+                   (magit-find-section (magit-section-path s)
+                                       magit-old-top-section))))
+    (if magit-top-section
+        (push s (magit-section-children magit-top-section))
+      (setq magit-top-section s))
+    (if old
+        (setf (magit-section-hidden s) (magit-section-hidden old)))
+    s))
+
+(defun magit-cancel-section (section)
+  "Delete the section SECTION."
+  (delete-region (magit-section-beginning section)
+                 (magit-section-end section))
+  (let ((parent (magit-section-parent section)))
+    (if parent
+        (setf (magit-section-children parent)
+              (delq section (magit-section-children parent)))
+      (setq magit-top-section nil))))
+
+(defmacro magit-with-section (title type &rest body)
+  "Create a new section of title TITLE and type TYPE and evaluate BODY there.
+
+Sections created inside BODY will become children of the new
+section. BODY must leave point at the end of the created section.
+
+If TYPE is nil, the section won't be highlighted."
+  (declare (indent 2))
+  (let ((s (make-symbol "*section*")))
+    `(let* ((,s (magit-new-section ,title ,type))
+            (magit-top-section ,s))
+       (setf (magit-section-beginning ,s) (point))
+       ,@body
+       (setf (magit-section-end ,s) (point))
+       (setf (magit-section-children ,s)
+             (nreverse (magit-section-children ,s)))
+       ,s)))
+
+(defun magit-set-section (title type start end)
+  "Create a new section of title TITLE and type TYPE with specified start and
+end positions."
+  (let ((section (magit-new-section title type)))
+    (setf (magit-section-beginning section) start)
+    (setf (magit-section-end section) end)
+    section))
+
+(defun magit-set-section-info (info &optional section)
+  (setf (magit-section-info (or section magit-top-section)) info))
+
+(defun magit-set-section-needs-refresh-on-show (flag &optional section)
+  (setf (magit-section-needs-refresh-on-show
+         (or section magit-top-section))
+        flag))
+
+(defmacro magit-create-buffer-sections (&rest body)
+  "Empty current buffer of text and Magit's sections, and then evaluate BODY."
+  (declare (indent 0))
+  `(let ((inhibit-read-only t))
+     (erase-buffer)
+     (let ((magit-old-top-section magit-top-section))
+       (setq magit-top-section nil)
+       ,@body
+       (when (null magit-top-section)
+         (magit-with-section 'top nil
+           (insert "(empty)\n")))
+       (magit-propertize-section magit-top-section)
+       (magit-section-set-hidden magit-top-section
+                                 (magit-section-hidden magit-top-section)))))
+
+(defun magit-propertize-section (section)
+  "Add text-property needed for SECTION."
+  (put-text-property (magit-section-beginning section)
+                     (magit-section-end section)
+                     'magit-section section)
+  (dolist (s (magit-section-children section))
+    (magit-propertize-section s)))
+
+(defun magit-find-section (path top)
+  "Find the section at the path PATH in subsection of section TOP."
+  (if (null path)
+      top
+    (let ((secs (magit-section-children top)))
+      (while (and secs (not (equal (car path)
+                                   (magit-section-title (car secs)))))
+        (setq secs (cdr secs)))
+      (and (car secs)
+           (magit-find-section (cdr path) (car secs))))))
+
+(defun magit-section-path (section)
+  "Return the path of SECTION."
+  (if (not (magit-section-parent section))
+      '()
+    (append (magit-section-path (magit-section-parent section))
+            (list (magit-section-title section)))))
+
+(defun magit-find-section-after (pos)
+  "Find the first section that begins after POS."
+  (magit-find-section-after* pos (list magit-top-section)))
+
+(defun magit-find-section-after* (pos secs)
+  "Find the first section that begins after POS in the list SECS
+\(including children of sections in SECS)."
+  (while (and secs
+              (<= (magit-section-beginning (car secs)) pos))
+    (setq secs (if (magit-section-hidden (car secs))
+                   (cdr secs)
+                 (append (magit-section-children (car secs))
+                         (cdr secs)))))
+  (car secs))
+
+(defun magit-find-section-before (pos)
+  "Return the last section that begins before POS."
+  (let ((section (magit-find-section-at pos)))
+    (do* ((current (or (magit-section-parent section)
+                       section)
+                   next)
+          (next (if (not (magit-section-hidden current))
+                    (magit-find-section-before* pos (magit-section-children current)))
+                (if (not (magit-section-hidden current))
+                    (magit-find-section-before* pos (magit-section-children current)))))
+        ((null next) current))))
+
+(defun magit-find-section-before* (pos secs)
+  "Find the last section that begins before POS in the list SECS."
+  (let ((prev nil))
+    (while (and secs
+                (< (magit-section-beginning (car secs)) pos))
+      (setq prev (car secs))
+      (setq secs (cdr secs)))
+    prev))
+
+(defun magit-current-section ()
+  "Return the Magit section at point."
+  (magit-find-section-at (point)))
+
+(defun magit-find-section-at (pos)
+  "Return the Magit section at POS."
+  (or (get-text-property pos 'magit-section)
+      magit-top-section))
+
+(defun magit-insert-section (section-title-and-type
+                             buffer-title washer cmd &rest args)
+  "Run CMD and put its result in a new section.
+
+SECTION-TITLE-AND-TYPE is either a string that is the title of the section
+or (TITLE . TYPE) where TITLE is the title of the section and TYPE is its type.
+
+If there is no type, or if type is nil, the section won't be highlighted.
+
+BUFFER-TITLE is the inserted title of the section
+
+WASHER is a function that will be run after CMD.
+The buffer will be narrowed to the inserted text.
+It should add sectioning as needed for Magit interaction.
+
+CMD is an external command that will be run with ARGS as arguments."
+  (let* ((body-beg nil)
+         (section-title (if (consp section-title-and-type)
+                            (car section-title-and-type)
+                          section-title-and-type))
+         (section-type (if (consp section-title-and-type)
+                           (cdr section-title-and-type)
+                         nil))
+         (section
+          (magit-with-section section-title section-type
+            (if buffer-title
+                (insert (propertize buffer-title 'face 'magit-section-title)
+                        "\n"))
+            (setq body-beg (point))
+            (magit-cmd-insert cmd args)
+            (if (not (eq (char-before) ?\n))
+                (insert "\n"))
+            (if washer
+                (save-restriction
+                  (narrow-to-region body-beg (point))
+                  (goto-char (point-min))
+                  (funcall washer)
+                  (goto-char (point-max)))))))
+    (if (= body-beg (point))
+        (magit-cancel-section section)
+      (insert "\n"))
+    section))
+
+(defun magit-git-section (section-title-and-type
+                          buffer-title washer &rest args)
+  "Run git and put its result in a new section.
+
+see `magit-insert-section' for meaning of the arguments"
+  (apply #'magit-insert-section
+         section-title-and-type
+         buffer-title
+         washer
+         magit-git-executable
+         (append magit-git-standard-options args)))
+
+(defun magit-goto-next-section ()
+  "Go to the next section."
+  (interactive)
+  (let ((next (magit-find-section-after (point))))
+    (if next
+        (magit-goto-section next)
+      (message "No next section"))))
+
+(defun magit-goto-previous-section ()
+  "Go to the previous section."
+  (interactive)
+  (if (eq (point) 1)
+      (message "No previous section")
+    (magit-goto-section (magit-find-section-before (point)))))
+
+(defun magit-goto-parent-section ()
+  "Go to the parent section."
+  (interactive)
+  (let ((parent (magit-section-parent (magit-current-section))))
+    (when parent
+      (goto-char (magit-section-beginning parent)))))
+
+(defun magit-goto-next-sibling-section ()
+  "Go to the next sibling section."
+  (interactive)
+  (let* ((initial (point))
+         (section (magit-current-section))
+         (end (- (magit-section-end section) 1))
+         (parent (magit-section-parent section))
+         (siblings (magit-section-children parent))
+         (next-sibling (magit-find-section-after* end siblings)))
+    (if next-sibling
+        (magit-goto-section next-sibling)
+      (magit-goto-next-section))))
+
+(defun magit-goto-previous-sibling-section ()
+  "Go to the previous sibling section."
+  (interactive)
+  (let* ((section (magit-current-section))
+         (beginning (magit-section-beginning section))
+         (parent (magit-section-parent section))
+         (siblings (magit-section-children parent))
+         (previous-sibling (magit-find-section-before* beginning siblings)))
+    (if previous-sibling
+        (magit-goto-section previous-sibling)
+      (magit-goto-parent-section))))
+
+(defun magit-goto-section (section)
+  (goto-char (magit-section-beginning section))
+  (cond
+   ((and magit-log-auto-more
+         (eq (magit-section-type section) 'longer))
+    (magit-log-show-more-entries)
+    (forward-line -1)
+    (magit-goto-next-section))
+   ((and (eq (magit-section-type section) 'commit)
+         (derived-mode-p 'magit-log-mode))
+    (magit-show-commit section))))
+
+(defun magit-goto-section-at-path (path)
+  "Go to the section described by PATH."
+  (let ((sec (magit-find-section path magit-top-section)))
+    (if sec
+        (goto-char (magit-section-beginning sec))
+      (message "No such section"))))
+
+(defun magit-for-all-sections (func &optional top)
+  "Run FUNC on TOP and recursively on all its children.
+
+Default value for TOP is `magit-top-section'"
+  (let ((section (or top magit-top-section)))
+    (when section
+      (funcall func section)
+      (dolist (c (magit-section-children section))
+        (magit-for-all-sections func c)))))
+
+(defun magit-section-set-hidden (section hidden)
+  "Hide SECTION if HIDDEN is not nil, show it otherwise."
+  (setf (magit-section-hidden section) hidden)
+  (if (and (not hidden)
+           (magit-section-needs-refresh-on-show section))
+      (magit-refresh)
+    (let ((inhibit-read-only t)
+          (beg (save-excursion
+                 (goto-char (magit-section-beginning section))
+                 (forward-line)
+                 (point)))
+          (end (magit-section-end section)))
+      (if (< beg end)
+          (put-text-property beg end 'invisible hidden)))
+    (if (not hidden)
+        (dolist (c (magit-section-children section))
+          (magit-section-set-hidden c (magit-section-hidden c))))))
+
+(defun magit-section-any-hidden (section)
+  "Return true if SECTION or any of its children is hidden."
+  (or (magit-section-hidden section)
+      (let ((kids (magit-section-children section)))
+        (while (and kids (not (magit-section-any-hidden (car kids))))
+          (setq kids (cdr kids)))
+        kids)))
+
+(defun magit-section-collapse (section)
+  "Show SECTION and hide all its children."
+  (dolist (c (magit-section-children section))
+    (setf (magit-section-hidden c) t))
+  (magit-section-set-hidden section nil))
+
+(defun magit-section-expand (section)
+  "Show SECTION and all its children."
+  (dolist (c (magit-section-children section))
+    (setf (magit-section-hidden c) nil))
+  (magit-section-set-hidden section nil))
+
+(defun magit-section-expand-all-aux (section)
+  "Show recursively all SECTION's children."
+  (dolist (c (magit-section-children section))
+    (setf (magit-section-hidden c) nil)
+    (magit-section-expand-all-aux c)))
+
+(defun magit-section-expand-all (section)
+  "Show SECTION and all its children."
+  (magit-section-expand-all-aux section)
+  (magit-section-set-hidden section nil))
+
+(defun magit-section-hideshow (flag-or-func)
+  "Show or hide current section depending on FLAG-OR-FUNC.
+
+If FLAG-OR-FUNC is a function, it will be ran on current section
+IF FLAG-OR-FUNC is a Boolean value, the section will be hidden if its true, shown otherwise"
+  (let ((section (magit-current-section)))
+    (when (magit-section-parent section)
+      (goto-char (magit-section-beginning section))
+      (if (functionp flag-or-func)
+          (funcall flag-or-func section)
+        (magit-section-set-hidden section flag-or-func)))))
+
+(defun magit-show-section ()
+  "Show current section."
+  (interactive)
+  (magit-section-hideshow nil))
+
+(defun magit-hide-section ()
+  "Hide current section."
+  (interactive)
+  (magit-section-hideshow t))
+
+(defun magit-collapse-section ()
+  "Hide all subsection of current section."
+  (interactive)
+  (magit-section-hideshow #'magit-section-collapse))
+
+(defun magit-expand-section ()
+  "Show all subsection of current section."
+  (interactive)
+  (magit-section-hideshow #'magit-section-expand))
+
+(defun magit-toggle-file-section ()
+  "Like `magit-toggle-section' but toggle at file granularity."
+  (interactive)
+  (when (eq 'hunk (first (magit-section-context-type (magit-current-section))))
+    (magit-goto-parent-section))
+  (magit-toggle-section))
+
+(defun magit-toggle-section ()
+  "Toggle hidden status of current section."
+  (interactive)
+  (magit-section-hideshow
+   (lambda (s)
+     (magit-section-set-hidden s (not (magit-section-hidden s))))))
+
+(defun magit-expand-collapse-section ()
+  "Toggle hidden status of subsections of current section."
+  (interactive)
+  (magit-section-hideshow
+   (lambda (s)
+     (cond ((magit-section-any-hidden s)
+            (magit-section-expand-all s))
+           (t
+            (magit-section-collapse s))))))
+
+(defun magit-cycle-section ()
+  "Cycle between expanded, hidden and collapsed state for current section.
+
+Hidden: only the first line of the section is shown
+Collapsed: only the first line of the subsection is shown
+Expanded: everything is shown."
+  (interactive)
+  (magit-section-hideshow
+   (lambda (s)
+     (cond ((magit-section-hidden s)
+            (magit-section-collapse s))
+           ((notany #'magit-section-hidden (magit-section-children s))
+            (magit-section-set-hidden s t))
+           (t
+            (magit-section-expand s))))))
+
+(defun magit-section-lineage (s)
+  "Return list of parent, grand-parents... for section S."
+  (when s
+    (cons s (magit-section-lineage (magit-section-parent s)))))
+
+(defun magit-section-show-level (section level threshold path)
+  (magit-section-set-hidden section (>= level threshold))
+  (when (and (< level threshold)
+             (not (magit-no-commit-p)))
+    (if path
+        (magit-section-show-level (car path) (1+ level) threshold (cdr path))
+      (dolist (c (magit-section-children section))
+        (magit-section-show-level c (1+ level) threshold nil)))))
+
+(defun magit-show-level (level all)
+  "Show section whose level is less than LEVEL, hide the others.
+If ALL is non nil, do this in all sections,
+otherwise do it only on ancestors and descendants of current section."
+  (magit-with-refresh
+    (if all
+        (magit-section-show-level magit-top-section 0 level nil)
+      (let ((path (reverse (magit-section-lineage (magit-current-section)))))
+        (magit-section-show-level (car path) 0 level (cdr path))))))
+
+(defun magit-show-only-files ()
+  "Show section that are files, but not there subsection.
+
+Do this in on ancestors and descendants of current section."
+  (interactive)
+  (if (derived-mode-p 'magit-status-mode)
+      (call-interactively 'magit-show-level-2)
+    (call-interactively 'magit-show-level-1)))
+
+(defun magit-show-only-files-all ()
+  "Show section that are files, but not there subsection.
+
+Do this for all sections"
+  (interactive)
+  (if (derived-mode-p 'magit-status-mode)
+      (call-interactively 'magit-show-level-2-all)
+    (call-interactively 'magit-show-level-1-all)))
+
+(defmacro magit-define-level-shower-1 (level all)
+  "Define an interactive function to show function of level LEVEL.
+
+If ALL is non nil, this function will affect all section,
+otherwise it will affect only ancestors and descendants of current section."
+  (let ((fun (intern (format "magit-show-level-%s%s"
+                             level (if all "-all" ""))))
+        (doc (format "Show sections on level %s." level)))
+    `(defun ,fun ()
+       ,doc
+       (interactive)
+       (magit-show-level ,level ,all))))
+
+(defmacro magit-define-level-shower (level)
+  "Define two interactive function to show function of level LEVEL.
+one for all, one for current lineage."
+  `(progn
+     (magit-define-level-shower-1 ,level nil)
+     (magit-define-level-shower-1 ,level t)))
+
+(defmacro magit-define-section-jumper (sym title)
+  "Define an interactive function to go to section SYM.
+
+TITLE is the displayed title of the section."
+  (let ((fun (intern (format "magit-jump-to-%s" sym)))
+        (doc (format "Jump to section `%s'." title)))
+    `(progn
+       (defun ,fun ()
+         ,doc
+         (interactive)
+         (magit-goto-section-at-path '(,sym)))
+       (put ',fun 'definition-name ',sym))))
+
+(defmacro magit-define-inserter (sym arglist &rest body)
+  (declare (indent defun))
+  (let ((fun (intern (format "magit-insert-%s" sym)))
+        (before (intern (format "magit-before-insert-%s-hook" sym)))
+        (after (intern (format "magit-after-insert-%s-hook" sym)))
+        (doc (format "Insert items for `%s'." sym)))
+    `(progn
+       (defvar ,before nil)
+       (defvar ,after nil)
+       (defun ,fun ,arglist
+         ,doc
+         (run-hooks ',before)
+         ,@body
+         (run-hooks ',after))
+       (put ',before 'definition-name ',sym)
+       (put ',after 'definition-name ',sym)
+       (put ',fun 'definition-name ',sym))))
+
+(defvar magit-highlighted-section nil)
+
+(defun magit-refine-section (section)
+  "Apply temporary refinements to the display of SECTION.
+Refinements can be undone with `magit-unrefine-section'."
+  (let ((type (and section (magit-section-type section))))
+    (cond ((and (eq type 'hunk)
+                magit-diff-refine-hunk
+                (not (eq magit-diff-refine-hunk 'all)))
+           ;; Refine the current hunk to show fine details, using
+           ;; diff-mode machinery.
+           (save-excursion
+             (goto-char (magit-section-beginning magit-highlighted-section))
+             (diff-refine-hunk))))))
+
+(defun magit-unrefine-section (section)
+  "Remove refinements to the display of SECTION done by `magit-refine-section'."
+  (let ((type (and section (magit-section-type section))))
+    (cond ((and (eq type 'hunk)
+                magit-diff-refine-hunk
+                (not (eq magit-diff-refine-hunk 'all)))
+           ;; XXX this should be in some diff-mode function, like
+           ;; `diff-unrefine-hunk'
+           (remove-overlays (magit-section-beginning section)
+                            (magit-section-end section)
+                            'diff-mode 'fine)))))
+
+(defvar magit-highlight-overlay nil)
+
+(defun magit-highlight-section ()
+  "Highlight current section if it has a type."
+  (let ((section (magit-current-section)))
+    (when (not (eq section magit-highlighted-section))
+      (when magit-highlighted-section
+        ;; remove any refinement from previous hunk
+        (magit-unrefine-section magit-highlighted-section))
+      (setq magit-highlighted-section section)
+      (if (not magit-highlight-overlay)
+          (let ((ov (make-overlay 1 1)))
+            (overlay-put ov 'face 'magit-item-highlight)
+            (setq magit-highlight-overlay ov)))
+      (if (and section (magit-section-type section))
+          (progn
+            (magit-refine-section section)
+            (move-overlay magit-highlight-overlay
+                          (magit-section-beginning section)
+                          (magit-section-end section)
+                          (current-buffer)))
+        (delete-overlay magit-highlight-overlay)))))
+
+(defun magit-section-context-type (section)
+  (if (null section)
+      '()
+    (let ((c (or (magit-section-type section)
+                 (if (symbolp (magit-section-title section))
+                     (magit-section-title section)))))
+      (if c
+          (cons c (magit-section-context-type
+                   (magit-section-parent section)))
+        '()))))
+
+(defun magit-prefix-p (prefix list)
+  "Returns non-nil if PREFIX is a prefix of LIST.  PREFIX and LIST should both be
+lists.
+
+If the car of PREFIX is the symbol '*, then return non-nil if the cdr of PREFIX
+is a sublist of LIST (as if '* matched zero or more arbitrary elements of LIST)"
+  ;;; Very schemish...
+  (or (null prefix)
+      (if (eq (car prefix) '*)
+          (or (magit-prefix-p (cdr prefix) list)
+              (and (not (null list))
+                   (magit-prefix-p prefix (cdr list))))
+        (and (not (null list))
+             (equal (car prefix) (car list))
+             (magit-prefix-p (cdr prefix) (cdr list))))))
+
+(defmacro magit-section-case (head &rest clauses)
+  "Make different action depending of current section.
+
+HEAD is (SECTION INFO &optional OPNAME),
+  SECTION will be bind to the current section,
+  INFO will be bind to the info's of the current section,
+  OPNAME is a string that will be used to describe current action,
+
+CLAUSES is a list of CLAUSE, each clause is (SECTION-TYPE &BODY)
+where SECTION-TYPE describe section where BODY will be run.
+
+This returns non-nil if some section matches. If the
+corresponding body return a non-nil value, it is returned,
+otherwise it returns t.
+
+If no section matches, this returns nil if no OPNAME was given
+and throws an error otherwise."
+  (declare (indent 1))
+  (let ((section (car head))
+        (info (cadr head))
+        (type (make-symbol "*type*"))
+        (context (make-symbol "*context*"))
+        (opname (caddr head)))
+    `(let* ((,section (magit-current-section))
+            (,info (and ,section (magit-section-info ,section)))
+            (,type (and ,section (magit-section-type ,section)))
+            (,context (magit-section-context-type ,section)))
+       (cond ,@(mapcar (lambda (clause)
+                         (if (eq (car clause) t)
+                             `(t (or (progn ,@(cdr clause))
+                                     t))
+                           (let ((prefix (reverse (car clause)))
+                                 (body (cdr clause)))
+                             `((magit-prefix-p ',prefix ,context)
+                               (or (progn ,@body)
+                                   t)))))
+                       clauses)
+             ,@(when opname
+                 `(((run-hook-with-args-until-success
+                     ',(intern (format "magit-%s-action-hook" opname))))
+                   ((not ,type)
+                    (error "Nothing to %s here" ,opname))
+                   (t
+                    (error "Can't %s a %s"
+                           ,opname
+                           (or (get ,type 'magit-description)
+                               ,type)))))))))
+
+(defmacro magit-section-action (head &rest clauses)
+  (declare (indent 1))
+  `(magit-with-refresh
+     (magit-section-case ,head ,@clauses)))
+
+(defmacro magit-add-action (head &rest clauses)
+  "Add additional actions to a pre-existing operator.
+The syntax is identical to `magit-section-case', except that
+OPNAME is mandatory and specifies the operation to which to add
+the actions."
+  (declare (indent 1))
+  (let ((section (car head))
+        (info (cadr head))
+        (type (caddr head)))
+    `(add-hook ',(intern (format "magit-%s-action-hook" type))
+               (lambda ()
+                 ,(macroexpand
+                   ;; Don't pass in the opname so we don't recursively
+                   ;; run the hook again, and so we don't throw an
+                   ;; error if no action matches.
+                   `(magit-section-case (,section ,info)
+                      ,@clauses))))))
+
+(defun magit-wash-sequence (func)
+  "Run FUNC until end of buffer is reached.
+
+FUNC should leave point at the end of the modified region"
+  (while (and (not (eobp))
+              (funcall func))))
+
+(defmacro magit-define-command (sym arglist &rest body)
+  "Macro to define a magit command.
+It will define the magit-SYM function having ARGLIST as argument.
+It will also define the magit-SYM-command-hook variable.
+
+The defined function will call the function in the hook in
+order until one return non nil. If they all return nil then body will be called.
+
+It is used to define hookable magit command: command defined by this
+function can be enriched by magit extension like magit-topgit and magit-svn"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]        ; Match the doc string, if present.
+                           [&optional ("interactive" interactive)]
+                           def-body)))
+  (let ((fun (intern (format "magit-%s" sym)))
+        (hook (intern (format "magit-%s-command-hook" sym)))
+        (doc (format "Command for `%s'." sym))
+        (inter nil)
+        (instr body))
+    (when (stringp (car body))
+      (setq doc (car body)
+            instr (cdr body)))
+    (let ((form (car instr)))
+      (when (eq (car form) 'interactive)
+        (setq inter form
+              instr (cdr instr))))
+    `(progn
+       (defvar ,hook nil)
+       (defun ,fun ,arglist
+         ,doc
+         ,inter
+         (or (run-hook-with-args-until-success
+              ',hook ,@(remq '&optional (remq '&rest arglist)))
+             ,@instr))
+       (put ',fun 'definition-name ',sym)
+       (put ',hook 'definition-name ',sym))))
+
+;;; Running commands
+
+(defun magit-set-mode-line-process (str)
+  (let ((pr (if str (concat " " str) "")))
+    (save-excursion
+      (magit-for-all-buffers (lambda ()
+                               (setq mode-line-process pr))))))
+
+(defun magit-process-indicator-from-command (comps)
+  (if (magit-prefix-p (cons magit-git-executable magit-git-standard-options)
+                      comps)
+      (setq comps (nthcdr (+ (length magit-git-standard-options) 1) comps)))
+  (cond ((or (null (cdr comps))
+             (not (member (car comps) '("remote"))))
+         (car comps))
+        (t
+         (concat (car comps) " " (cadr comps)))))
+
+(defvar magit-process nil)
+(defvar magit-process-client-buffer nil)
+(defvar magit-process-buffer-name "*magit-process*"
+  "Buffer name for running git commands.")
+
+(defun magit-run* (cmd-and-args
+                   &optional logline noerase noerror nowait input)
+  (if (and magit-process
+           (get-buffer magit-process-buffer-name))
+      (error "Git is already running"))
+  (let ((cmd (car cmd-and-args))
+        (args (cdr cmd-and-args))
+        (dir default-directory)
+        (buf (get-buffer-create magit-process-buffer-name))
+        (successp nil))
+    (magit-set-mode-line-process
+     (magit-process-indicator-from-command cmd-and-args))
+    (setq magit-process-client-buffer (current-buffer))
+    (with-current-buffer buf
+      (view-mode 1)
+      (set (make-local-variable 'view-no-disable-on-exit) t)
+      (setq view-exit-action
+            (lambda (buffer)
+              (with-current-buffer buffer
+                (bury-buffer))))
+      (setq buffer-read-only t)
+      (let ((inhibit-read-only t))
+        (setq default-directory dir)
+        (if noerase
+            (goto-char (point-max))
+          (erase-buffer))
+        (insert "$ " (or logline
+                         (mapconcat 'identity cmd-and-args " "))
+                "\n")
+        (cond (nowait
+               (setq magit-process
+                     (let ((process-connection-type magit-process-connection-type))
+                       (apply 'magit-start-process cmd buf cmd args)))
+               (set-process-sentinel magit-process 'magit-process-sentinel)
+               (set-process-filter magit-process 'magit-process-filter)
+               (when input
+                 (with-current-buffer input
+                   (process-send-region magit-process
+                                        (point-min) (point-max)))
+                 (process-send-eof magit-process)
+                 (sit-for 0.1 t))
+               (cond ((= magit-process-popup-time 0)
+                      (pop-to-buffer (process-buffer magit-process)))
+                     ((> magit-process-popup-time 0)
+                      (run-with-timer
+                       magit-process-popup-time nil
+                       (function
+                        (lambda (buf)
+                          (with-current-buffer buf
+                            (when magit-process
+                              (display-buffer (process-buffer magit-process))
+                              (goto-char (point-max))))))
+                       (current-buffer))))
+               (setq successp t))
+              (input
+               (with-current-buffer input
+                 (setq default-directory dir)
+                 (setq magit-process
+                       ;; Don't use a pty, because it would set icrnl
+                       ;; which would modify the input (issue #20).
+                       (let ((process-connection-type nil))
+                         (apply 'magit-start-process cmd buf cmd args)))
+                 (set-process-filter magit-process 'magit-process-filter)
+                 (process-send-region magit-process
+                                      (point-min) (point-max))
+                 (process-send-eof magit-process)
+                 (while (equal (process-status magit-process) 'run)
+                   (sit-for 0.1 t))
+                 (setq successp
+                       (equal (process-exit-status magit-process) 0))
+                 (setq magit-process nil))
+               (magit-set-mode-line-process nil)
+               (magit-need-refresh magit-process-client-buffer))
+              (t
+               (setq successp
+                     (equal (apply 'process-file cmd nil buf nil args) 0))
+               (magit-set-mode-line-process nil)
+               (magit-need-refresh magit-process-client-buffer))))
+      (or successp
+          noerror
+          (error
+           "%s ... [Hit %s or see buffer %s for details]"
+           (or (with-current-buffer (get-buffer magit-process-buffer-name)
+                 (when (re-search-backward
+                        (concat "^error: \\(.*\\)" paragraph-separate) nil t)
+                   (match-string 1)))
+               "Git failed")
+           (with-current-buffer magit-process-client-buffer
+             (key-description (car (where-is-internal
+                                    'magit-display-process))))
+           magit-process-buffer-name))
+      successp)))
+
+(autoload 'dired-uncache "dired")
+(defun magit-process-sentinel (process event)
+  (let ((msg (format "%s %s." (process-name process) (substring event 0 -1)))
+        (successp (string-match "^finished" event))
+        (key (with-current-buffer magit-process-client-buffer
+               (key-description (car (where-is-internal
+                                      'magit-display-process))))))
+    (with-current-buffer (process-buffer process)
+      (let ((inhibit-read-only t))
+        (goto-char (point-max))
+        (insert msg "\n")
+        (message (if successp msg
+                   (format "%s Hit %s or see buffer %s for details."
+                           msg key (current-buffer)))))
+      (unless (memq (process-status process) '(run open))
+        (dired-uncache default-directory)))
+    (setq magit-process nil)
+    (magit-set-mode-line-process nil)
+    (magit-refresh-buffer magit-process-client-buffer)))
+
+(defun magit-password (proc string)
+  "Checks if git/ssh asks for a password and ask the user for it."
+  (let (ask)
+    (cond ((or (string-match "^Enter passphrase for key '\\\(.*\\\)': $" string)
+               (string-match "^\\\(.*\\\)'s password:" string)
+               (string-match "^Password for '\\\(.*\\\)':" string))
+           (setq ask (format "Password for '%s': " (match-string 1 string))))
+          ((string-match "^[pP]assword:" string)
+           (setq ask "Password:")))
+    (when ask
+      (process-send-string proc (concat (read-passwd ask nil) "\n")))))
+
+(defun magit-username (proc string)
+  "Checks if git asks for a username and ask the user for it."
+  (when (string-match "^Username for '\\\(.*\\\)':" string)
+    (process-send-string proc
+                         (concat
+                          (read-string (format "Username for '%s': "
+                                               (match-string 1 string))
+                                       nil nil (user-login-name))
+                          "\n"))))
+
+(defun magit-process-filter (proc string)
+  (save-current-buffer
+    (set-buffer (process-buffer proc))
+    (let ((inhibit-read-only t))
+      (magit-username proc string)
+      (magit-password proc string)
+      (goto-char (process-mark proc))
+      ;; Find last ^M in string.  If one was found, ignore everything
+      ;; before it and delete the current line.
+      (let ((ret-pos (length string)))
+        (while (and (>= (setq ret-pos (1- ret-pos)) 0)
+                    (/= ?\r (aref string ret-pos))))
+        (cond ((>= ret-pos 0)
+               (goto-char (line-beginning-position))
+               (delete-region (point) (line-end-position))
+               (insert (substring string (+ ret-pos 1))))
+              (t
+               (insert string))))
+      (set-marker (process-mark proc) (point)))))
+
+(defun magit-run (cmd &rest args)
+  (magit-with-refresh
+    (magit-run* (cons cmd args))))
+
+(defun magit-run-git (&rest args)
+  (magit-with-refresh
+    (magit-run* (append (cons magit-git-executable
+                              magit-git-standard-options)
+                        args))))
+
+(defun magit-run-git-with-input (input &rest args)
+  (magit-with-refresh
+    (magit-run* (append (cons magit-git-executable
+                              magit-git-standard-options)
+                        args)
+                nil nil nil nil input)))
+
+(defun magit-run-git-async (&rest args)
+  (message "Running %s %s" magit-git-executable (mapconcat 'identity args " "))
+  (magit-run* (append (cons magit-git-executable
+                            magit-git-standard-options)
+                      args)
+              nil nil nil t))
+
+(defun magit-run-async-with-input (input cmd &rest args)
+  (magit-run* (cons cmd args) nil nil nil t input))
+
+(defun magit-display-process ()
+  "Display output from most recent git command."
+  (interactive)
+  (unless (get-buffer magit-process-buffer-name)
+    (error "No Git commands have run"))
+  (display-buffer magit-process-buffer-name))
+
+;;; Mode
+
+;; We define individual functions (instead of using lambda etc) so
+;; that the online help can show something meaningful.
+
+(magit-define-section-jumper untracked "Untracked files")
+(magit-define-section-jumper unstaged  "Unstaged changes")
+(magit-define-section-jumper staged    "Staged changes")
+(magit-define-section-jumper unpushed  "Unpushed commits")
+
+(magit-define-level-shower 1)
+(magit-define-level-shower 2)
+(magit-define-level-shower 3)
+(magit-define-level-shower 4)
+
+(easy-menu-define magit-mode-menu magit-mode-map
+  "Magit menu"
+  '("Magit"
+    ["Refresh" magit-refresh t]
+    ["Refresh all" magit-refresh-all t]
+    "---"
+    ["Stage" magit-stage-item t]
+    ["Stage all" magit-stage-all t]
+    ["Unstage" magit-unstage-item t]
+    ["Unstage all" magit-unstage-all t]
+    ["Commit" magit-log-edit t]
+    ["Add log entry" magit-add-log t]
+    ["Tag" magit-tag t]
+    ["Annotated tag" magit-annotated-tag t]
+    "---"
+    ["Diff working tree" magit-diff-working-tree t]
+    ["Diff" magit-diff t]
+    ("Log"
+     ["Short Log" magit-log t]
+     ["Long Log" magit-log-long t]
+     ["Reflog" magit-reflog t]
+     ["Extended..." magit-key-mode-popup-logging t])
+    "---"
+    ["Cherry pick" magit-cherry-pick-item t]
+    ["Apply" magit-apply-item t]
+    ["Revert" magit-revert-item t]
+    "---"
+    ["Ignore" magit-ignore-item t]
+    ["Ignore locally" magit-ignore-item-locally t]
+    ["Discard" magit-discard-item t]
+    ["Reset head" magit-reset-head t]
+    ["Reset working tree" magit-reset-working-tree t]
+    ["Stash" magit-stash t]
+    ["Snapshot" magit-stash-snapshot t]
+    "---"
+    ["Branch..." magit-checkout t]
+    ["Merge" magit-manual-merge t]
+    ["Interactive resolve" magit-interactive-resolve-item t]
+    ["Rebase" magit-rebase-step t]
+    ("Rewrite"
+     ["Start" magit-rewrite-start t]
+     ["Stop" magit-rewrite-stop t]
+     ["Finish" magit-rewrite-finish t]
+     ["Abort" magit-rewrite-abort t]
+     ["Set used" magit-rewrite-set-used t]
+     ["Set unused" magit-rewrite-set-unused t])
+    "---"
+    ["Push" magit-push t]
+    ["Pull" magit-pull t]
+    ["Remote update" magit-remote-update t]
+    ("Submodule"
+     ["Submodule update" magit-submodule-update t]
+     ["Submodule update and init" magit-submodule-update-init t]
+     ["Submodule init" magit-submodule-init t]
+     ["Submodule sync" magit-submodule-sync t])
+    "---"
+    ("Extensions")
+    "---"
+    ["Display Git output" magit-display-process t]
+    ["Quit Magit" magit-quit-window t]))
+
+(defvar magit-mode-hook nil "Hook run by `magit-mode'.")
+
+(put 'magit-mode 'mode-class 'special)
+
+(defvar magit-refresh-function nil)
+(make-variable-buffer-local 'magit-refresh-function)
+(put 'magit-refresh-function 'permanent-local t)
+
+(defvar magit-refresh-args nil)
+(make-variable-buffer-local 'magit-refresh-args)
+(put 'magit-refresh-args 'permanent-local t)
+
+(defvar last-point)
+
+(defun magit-remember-point ()
+  (setq last-point (point)))
+
+(defun magit-invisible-region-end (pos)
+  (while (and (not (= pos (point-max))) (invisible-p pos))
+    (setq pos (next-char-property-change pos)))
+  pos)
+
+(defun magit-invisible-region-start (pos)
+  (while (and (not (= pos (point-min))) (invisible-p pos))
+    (setq pos (1- (previous-char-property-change pos))))
+  pos)
+
+(defun magit-correct-point-after-command ()
+  "Move point outside of invisible regions.
+
+Emacs often leaves point in invisible regions, it seems.  To fix
+this, we move point ourselves and never let Emacs do its own
+adjustments.
+
+When point has to be moved out of an invisible region, it can be
+moved to its end or its beginning.  We usually move it to its
+end, except when that would move point back to where it was
+before the last command."
+  (if (invisible-p (point))
+      (let ((end (magit-invisible-region-end (point))))
+        (goto-char (if (= end last-point)
+                       (magit-invisible-region-start (point))
+                     end))))
+  (setq disable-point-adjustment t))
+
+(defun magit-post-command-hook ()
+  (magit-correct-point-after-command)
+  (magit-highlight-section))
+
+(defun magit-mode ()
+  "Review the status of a git repository and act on it.
+
+Please see the manual for a complete description of Magit.
+
+\\{magit-mode-map}"
+  (kill-all-local-variables)
+  (buffer-disable-undo)
+  (setq buffer-read-only t
+        truncate-lines t
+        major-mode 'magit-mode
+        mode-name "Magit"
+        mode-line-process "")
+  (add-hook 'pre-command-hook #'magit-remember-point nil t)
+  (add-hook 'post-command-hook #'magit-post-command-hook t t)
+  (use-local-map magit-mode-map)
+  (setq magit-current-indentation (magit-indentation-for default-directory))
+  ;; Emacs' normal method of showing trailing whitespace gives weird
+  ;; results when `magit-whitespace-warning-face' is different from
+  ;; `trailing-whitespace'.
+  (if (and magit-highlight-whitespace magit-highlight-trailing-whitespace)
+      (setq show-trailing-whitespace nil))
+  (run-mode-hooks 'magit-mode-hook))
+
+(defun magit-mode-init (dir submode refresh-func &rest refresh-args)
+  (setq default-directory dir
+        magit-refresh-function refresh-func
+        magit-refresh-args refresh-args)
+  (funcall submode)
+  (magit-refresh-buffer))
+
+(defun magit-indentation-for (dir)
+  (let (result)
+    (dolist (pair magit-highlight-indentation)
+      (if (string-match-p (car pair) dir)
+          (setq result (cdr pair))))
+    result))
+
+(defun magit-find-buffer (submode &optional dir)
+  (let ((topdir (magit-get-top-dir (or dir default-directory))))
+    (dolist (buf (buffer-list))
+      (if (with-current-buffer buf
+            (and (eq major-mode submode)
+                 default-directory
+                 (equal (expand-file-name default-directory) topdir)))
+          (return buf)))))
+
+(defun magit-find-status-buffer (&optional dir)
+  (magit-find-buffer 'magit-status-mode dir))
+
+(defun magit-for-all-buffers (func &optional dir)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (if (and (derived-mode-p 'magit-mode)
+               (or (null dir)
+                   (equal default-directory dir)))
+          (funcall func)))))
+
+(defun magit-refresh-buffer (&optional buffer)
+  (with-current-buffer (or buffer (current-buffer))
+    (let* ((old-line (line-number-at-pos))
+           (old-point (point))
+           (old-section (magit-current-section))
+           (old-path (and old-section
+                          (magit-section-path (magit-current-section)))))
+      (beginning-of-line)
+      (let ((section-line (and old-section
+                               (count-lines
+                                (magit-section-beginning old-section)
+                                (point))))
+            (line-char (- old-point (point))))
+        (if magit-refresh-function
+            (apply magit-refresh-function
+                   magit-refresh-args))
+        (magit-refresh-marked-commits-in-buffer)
+        (let ((s (and old-path (magit-find-section old-path magit-top-section))))
+          (cond (s
+                 (goto-char (magit-section-beginning s))
+                 (forward-line section-line)
+                 (forward-char line-char))
+                (t
+                 (magit-goto-line old-line)))
+          (dolist (w (get-buffer-window-list (current-buffer)))
+            (set-window-point w (point)))
+          (magit-highlight-section))))))
+
+(defun magit-string-has-prefix-p (string prefix)
+  (eq (compare-strings string nil (length prefix) prefix nil nil) t))
+
+(defun magit-revert-buffers (dir &optional ignore-modtime)
+  (dolist (buffer (buffer-list))
+    (when (and buffer
+               (buffer-file-name buffer)
+               ;; don't revert indirect buffers, as the parent will be reverted
+               (not (buffer-base-buffer buffer))
+               (magit-string-has-prefix-p (buffer-file-name buffer) dir)
+               (file-readable-p (buffer-file-name buffer))
+               (or ignore-modtime (not (verify-visited-file-modtime buffer)))
+               (not (buffer-modified-p buffer)))
+      (with-current-buffer buffer
+        (condition-case var
+            (revert-buffer t t nil)
+          (error (let ((signal-data (cadr var)))
+                   (cond (t (magit-bug-report signal-data))))))))))
+
+(defun magit-update-vc-modeline (dir)
+  "Update the modeline for buffers representable by magit."
+  (dolist (buffer (buffer-list))
+    (when (and buffer
+               (buffer-file-name buffer)
+               (magit-string-has-prefix-p (buffer-file-name buffer) dir))
+      (with-current-buffer buffer
+        (condition-case var
+            (vc-find-file-hook)
+          (error (let ((signal-data (cadr var)))
+                   (cond (t (magit-bug-report signal-data))))))))))
+
+(defvar magit-refresh-needing-buffers nil)
+(defvar magit-refresh-pending nil)
+
+(defun magit-refresh-wrapper (func)
+  (if magit-refresh-pending
+      (funcall func)
+    (let* ((dir default-directory)
+           (status-buffer (magit-find-status-buffer dir))
+           (magit-refresh-needing-buffers nil)
+           (magit-refresh-pending t))
+      (unwind-protect
+          (funcall func)
+        (when magit-refresh-needing-buffers
+          (magit-revert-buffers dir)
+          (dolist (b (adjoin status-buffer
+                             magit-refresh-needing-buffers))
+            (magit-refresh-buffer b)))))))
+
+(defun magit-need-refresh (&optional buffer)
+  "Mark BUFFER as needing to be refreshed.  If BUFFER is nil, use the
+current buffer."
+  (pushnew (or buffer (current-buffer)) magit-refresh-needing-buffers :test 'eq))
+
+(defun magit-refresh ()
+  "Refresh current buffer to match repository state.
+Also revert every unmodified buffer visiting files
+in the corresponding directory."
+  (interactive)
+  (magit-with-refresh
+    (magit-need-refresh)))
+
+(defun magit-refresh-all ()
+  "Refresh all magit buffers to match respective repository states.
+Also revert every unmodified buffer visiting files
+in the corresponding directories."
+  (interactive)
+  (magit-for-all-buffers #'magit-refresh-buffer default-directory))
+
+;;; Untracked files
+
+(defun magit-wash-untracked-file ()
+  (if (looking-at "^? \\(.*\\)$")
+      (let ((file (match-string-no-properties 1)))
+        (delete-region (point) (+ (line-end-position) 1))
+        (magit-with-section file 'file
+          (magit-set-section-info file)
+          (insert "\t" file "\n"))
+        t)
+    nil))
+
+(defun magit-wash-untracked-files ()
+  ;; Setting magit-old-top-section to nil speeds up washing: no time
+  ;; is wasted looking up the old visibility, which doesn't matter for
+  ;; untracked files.
+  ;;
+  ;; XXX - speed this up in a more general way.
+  ;;
+  (let ((magit-old-top-section nil))
+    (magit-wash-sequence #'magit-wash-untracked-file)))
+
+(defun magit-insert-untracked-files ()
+  (unless (string= (magit-get "status" "showUntrackedFiles") "no")
+    (apply 'magit-git-section
+           `(untracked
+             "Untracked files:"
+             magit-wash-untracked-files
+             "ls-files" "--others" "-t" "--exclude-standard"
+             ,@(when magit-omit-untracked-dir-contents
+                 '("--directory"))))))
+
+;;; Diffs and Hunks
+
+(defvar magit-diff-context-lines 3)
+
+(defun magit-diff-U-arg ()
+  (format "-U%d" magit-diff-context-lines))
+
+(defun magit-diff-smaller-hunks (&optional count)
+  "Decrease the context for diff hunks by COUNT."
+  (interactive "p")
+  (setq magit-diff-context-lines (max 0 (- magit-diff-context-lines count)))
+  (magit-refresh))
+
+(defun magit-diff-larger-hunks (&optional count)
+  "Increase the context for diff hunks by COUNT."
+  (interactive "p")
+  (setq magit-diff-context-lines (+ magit-diff-context-lines count))
+  (magit-refresh))
+
+(defun magit-diff-default-hunks ()
+  "Reset context for diff hunks to the default size."
+  (interactive "")
+  (setq magit-diff-context-lines 3)
+  (magit-refresh))
+
+(defun magit-toggle-diff-refine-hunk (&optional other)
+  (interactive "P")
+  "Turn diff-hunk refining on or off.
+
+If hunk refining is currently on, then hunk refining is turned off.
+If hunk refining is off, then hunk refining is turned on, in
+`selected' mode (only the currently selected hunk is refined).
+
+With a prefix argument, the \"third choice\" is used instead:
+If hunk refining is currently on, then refining is kept on, but
+the refining mode (`selected' or `all') is switched.
+If hunk refining is off, then hunk refining is turned on, in
+`all' mode (all hunks refined).
+
+Customize `magit-diff-refine-hunk' to change the default mode."
+  (let* ((old magit-diff-refine-hunk)
+         (new
+          (if other
+              (if (eq old 'all) t 'all)
+            (not old))))
+
+    ;; remove any old refining in currently highlighted section
+    (when (and magit-highlighted-section old (not (eq old 'all)))
+      (magit-unrefine-section magit-highlighted-section))
+
+    ;; set variable to new value locally
+    (set (make-local-variable 'magit-diff-refine-hunk) new)
+
+    ;; if now highlighting in "selected only" mode, turn refining back
+    ;; on in the current section
+    (when (and magit-highlighted-section new (not (eq new 'all)))
+      (magit-refine-section magit-highlighted-section))
+
+    ;; `all' mode being turned on or off needs a complete refresh
+    (when (or (eq old 'all) (eq new 'all))
+      (magit-refresh))))
+
+(defun magit-diff-line-file ()
+  (cond ((looking-at "^diff --git ./\\(.*\\) ./\\(.*\\)$")
+         (match-string-no-properties 2))
+        ((looking-at "^diff --cc +\\(.*\\)$")
+         (match-string-no-properties 1))
+        (t
+         nil)))
+
+(defun magit-wash-diffs ()
+  (magit-wash-sequence #'magit-wash-diff-or-other-file))
+
+(defun magit-wash-diff-or-other-file ()
+  (or (magit-wash-diff)
+      (magit-wash-other-file)))
+
+(defun magit-wash-other-file ()
+  (if (looking-at "^? \\(.*\\)$")
+      (let ((file (match-string-no-properties 1)))
+        (delete-region (point) (+ (line-end-position) 1))
+        (magit-with-section file 'file
+          (magit-set-section-info file)
+          (insert "\tNew      " file "\n"))
+        t)
+    nil))
+
+(defvar magit-hide-diffs nil)
+
+(defvar magit-indentation-level 1)
+
+(defun magit-insert-diff-title (status file file2)
+  (let ((status-text (case status
+                       ((unmerged)
+                        (format "Unmerged   %s" file))
+                       ((new)
+                        (format "New        %s" file))
+                       ((deleted)
+                        (format "Deleted    %s" file))
+                       ((renamed)
+                        (format "Renamed    %s   (from %s)"
+                                file file2))
+                       ((modified)
+                        (format "Modified   %s" file))
+                       ((typechange)
+                        (format "Typechange %s" file))
+                       (t
+                        (format "?          %s" file)))))
+    (insert (make-string magit-indentation-level ?\t) status-text "\n")))
+
+(defvar magit-current-diff-range nil
+  "Used internally when setting up magit diff sections.")
+
+(defun magit-wash-typechange-section (file)
+  (magit-set-section-info (list 'typechange file))
+  (let ((first-start (point-marker))
+        (second-start (progn (forward-line 1)
+                             (search-forward-regexp "^diff")
+                             (beginning-of-line)
+                             (point-marker))))
+    (let ((magit-indentation-level (+ magit-indentation-level 1)))
+      (save-restriction
+        (narrow-to-region first-start second-start)
+        (goto-char (point-min))
+        (magit-with-section file 'diff
+          (magit-wash-diff-section)))
+      (save-restriction
+        (narrow-to-region second-start (point-max))
+        (goto-char (point-min))
+        (magit-with-section file 'diff
+          (magit-wash-diff-section))))))
+
+(defun magit-wash-diff-section ()
+  (cond ((looking-at "^\\* Unmerged path \\(.*\\)")
+         (let ((file (match-string-no-properties 1)))
+           (delete-region (point) (line-end-position))
+           (insert "\tUnmerged " file "\n")
+           (magit-set-section-info (list 'unmerged file nil))
+           t))
+        ((looking-at "^diff")
+         (let ((file (magit-diff-line-file))
+               (end (save-excursion
+                      (forward-line) ;; skip over "diff" line
+                      (if (search-forward-regexp "^diff\\|^@@" nil t)
+                          (goto-char (match-beginning 0))
+                        (goto-char (point-max)))
+                      (point-marker))))
+           (let* ((status (cond
+                           ((looking-at "^diff --cc")
+                            'unmerged)
+                           ((save-excursion
+                              (search-forward-regexp "^new file" end t))
+                            'new)
+                           ((save-excursion
+                              (search-forward-regexp "^deleted" end t))
+                            'deleted)
+                           ((save-excursion
+                              (search-forward-regexp "^rename" end t))
+                            'renamed)
+                           (t
+                            'modified)))
+                  (file2 (cond
+                          ((save-excursion
+                             (search-forward-regexp "^rename from \\(.*\\)"
+                                                    end t))
+                           (match-string-no-properties 1)))))
+             (magit-set-section-info (list status
+                                           file
+                                           (or file2 file)
+                                           magit-current-diff-range))
+             (magit-insert-diff-title status file file2)
+             (when (search-forward-regexp "\\(--- \\(.*\\)\n\\+\\+\\+ \\(.*\\)\n\\)" () t)
+               (when (match-string 1)
+                 (add-text-properties (match-beginning 1) (match-end 1)
+                                      '(face magit-diff-hunk-header))
+                 (add-text-properties (match-beginning 2) (match-end 2)
+                                      '(face magit-diff-file-header))
+                 (add-text-properties (match-beginning 3) (match-end 3)
+                                      '(face magit-diff-file-header))))
+             (goto-char end)
+             (let ((magit-section-hidden-default nil))
+               (magit-wash-sequence #'magit-wash-hunk))))
+         t)
+        (t
+         nil)))
+
+(defun magit-wash-diff ()
+  (let ((magit-section-hidden-default magit-hide-diffs))
+    (magit-with-section (magit-current-line) 'diff
+      (magit-wash-diff-section))))
+
+(defun magit-diff-item-kind (diff)
+  (car (magit-section-info diff)))
+
+(defun magit-diff-item-file (diff)
+  (cadr (magit-section-info diff)))
+
+(defun magit-diff-item-file2 (diff)
+  (caddr (magit-section-info diff)))
+
+(defun magit-diff-item-range (diff)
+  (nth 3 (magit-section-info diff)))
+
+(defun magit-wash-hunk ()
+  (cond ((looking-at "\\(^@+\\)[^@]*@+.*")
+         (let ((n-columns (1- (length (match-string 1))))
+               (head (match-string 0))
+               (hunk-start-pos (point)))
+           (magit-with-section head 'hunk
+             (add-text-properties (match-beginning 0) (match-end 0)
+                                  '(face magit-diff-hunk-header))
+             (forward-line)
+             (while (not (or (eobp)
+                             (looking-at "^diff\\|^@@")))
+               (magit-highlight-line-whitespace)
+               (let ((prefix (buffer-substring-no-properties
+                              (point) (min (+ (point) n-columns) (point-max)))))
+                 (cond ((string-match "\\+" prefix)
+                        (magit-put-line-property 'face 'magit-diff-add))
+                       ((string-match "-" prefix)
+                        (magit-put-line-property 'face 'magit-diff-del))
+                       (t
+                        (magit-put-line-property 'face 'magit-diff-none))))
+               (forward-line)))
+
+           (when (eq magit-diff-refine-hunk 'all)
+             (save-excursion
+               (goto-char hunk-start-pos)
+               (diff-refine-hunk))))
+         t)
+        (t
+         nil)))
+
+(defvar magit-diff-options nil)
+
+(defun magit-insert-diff (file status)
+  (let ((cmd magit-git-executable)
+        (args (append (list "diff")
+                      (list (magit-diff-U-arg))
+                      magit-diff-options
+                      (list "--" file))))
+    (let ((p (point)))
+      (magit-git-insert args)
+      (if (not (eq (char-before) ?\n))
+          (insert "\n"))
+      (save-restriction
+        (narrow-to-region p (point))
+        (goto-char p)
+        (cond
+         ((eq status 'typechange)
+          (magit-insert-diff-title status file file)
+          (magit-wash-typechange-section file))
+         (t
+          (magit-wash-diff-section)))
+        (goto-char (point-max))))))
+
+(defvar magit-last-raw-diff nil)
+(defvar magit-ignore-unmerged-raw-diffs nil)
+
+(defun magit-wash-raw-diffs ()
+  (let ((magit-last-raw-diff nil))
+    (magit-wash-sequence #'magit-wash-raw-diff)))
+
+(defun magit-wash-raw-diff ()
+  (if (looking-at
+       ":\\([0-7]+\\) \\([0-7]+\\) [0-9a-f]+ [0-9a-f]+ \\(.\\)[0-9]*\t\\([^\t\n]+\\)$")
+      (let ((old-perm (match-string-no-properties 1))
+            (new-perm (match-string-no-properties 2))
+            (status (case (string-to-char (match-string-no-properties 3))
+                      (?A 'new)
+                      (?D 'deleted)
+                      (?M 'modified)
+                      (?U 'unmerged)
+                      (?T 'typechange)
+                      (t     nil)))
+            (file (match-string-no-properties 4)))
+        ;; If this is for the same file as the last diff, ignore it.
+        ;; Unmerged files seem to get two entries.
+        ;; We also ignore unmerged files when told so.
+        (if (or (equal file magit-last-raw-diff)
+                (and magit-ignore-unmerged-raw-diffs (eq status 'unmerged)))
+            (delete-region (point) (+ (line-end-position) 1))
+          (setq magit-last-raw-diff file)
+          ;; The 'diff' section that is created here will not work with
+          ;; magit-insert-diff-item-patch etc when we leave it empty.
+          ;; Luckily, raw diffs are only produced for staged and
+          ;; unstaged changes, and we never call
+          ;; magit-insert-diff-item-patch on them.  This is a bit
+          ;; brittle, of course.
+          (let ((magit-section-hidden-default magit-hide-diffs))
+            (magit-with-section file 'diff
+              (delete-region (point) (+ (line-end-position) 1))
+              (if (not (magit-section-hidden magit-top-section))
+                  (magit-insert-diff file status)
+                (magit-set-section-info (list status file nil))
+                (magit-set-section-needs-refresh-on-show t)
+                (magit-insert-diff-title status file nil)))))
+        t)
+    nil))
+
+(defun magit-hunk-item-diff (hunk)
+  (let ((diff (magit-section-parent hunk)))
+    (or (eq (magit-section-type diff) 'diff)
+        (error "Huh?  Parent of hunk not a diff"))
+    diff))
+
+(defun magit-diff-item-insert-header (diff buf)
+  (let ((beg (save-excursion
+               (goto-char (magit-section-beginning diff))
+               (forward-line)
+               (point)))
+        (end (if (magit-section-children diff)
+                 (magit-section-beginning (car (magit-section-children diff)))
+               (magit-section-end diff))))
+    (magit-insert-region beg end buf)))
+
+(defun magit-insert-diff-item-patch (diff buf)
+  (let ((beg (save-excursion
+               (goto-char (magit-section-beginning diff))
+               (forward-line)
+               (point)))
+        (end (magit-section-end diff)))
+    (magit-insert-region beg end buf)))
+
+(defun magit-insert-hunk-item-patch (hunk buf)
+  (magit-diff-item-insert-header (magit-hunk-item-diff hunk) buf)
+  (magit-insert-region (magit-section-beginning hunk) (magit-section-end hunk)
+                       buf))
+
+(defun magit-insert-hunk-item-region-patch (hunk reverse beg end buf)
+  (magit-diff-item-insert-header (magit-hunk-item-diff hunk) buf)
+  (save-excursion
+    (goto-char (magit-section-beginning hunk))
+    (magit-insert-current-line buf)
+    (forward-line)
+    (let ((copy-op (if reverse "+" "-")))
+      (while (< (point) (magit-section-end hunk))
+        (if (and (<= beg (point)) (< (point) end))
+            (magit-insert-current-line buf)
+          (cond ((looking-at " ")
+                 (magit-insert-current-line buf))
+                ((looking-at copy-op)
+                 (let ((text (buffer-substring-no-properties
+                              (+ (point) 1) (line-beginning-position 2))))
+                   (with-current-buffer buf
+                     (insert " " text))))))
+        (forward-line))))
+  (with-current-buffer buf
+    (diff-fixup-modifs (point-min) (point-max))))
+
+(defun magit-hunk-item-is-conflict-p (hunk)
+  ;;; XXX - Using the title is a bit too clever...
+  (string-match "^diff --cc"
+                (magit-section-title (magit-hunk-item-diff hunk))))
+
+(defun magit-hunk-item-target-line (hunk)
+  (save-excursion
+    (beginning-of-line)
+    (let ((line (line-number-at-pos)))
+      (goto-char (magit-section-beginning hunk))
+      (if (not (looking-at "@@+ .* \\+\\([0-9]+\\)\\(,[0-9]+\\)? @@+"))
+          (error "Hunk header not found"))
+      (let ((target (string-to-number (match-string 1))))
+        (forward-line)
+        (while (< (line-number-at-pos) line)
+          ;; XXX - deal with combined diffs
+          (if (not (looking-at "-"))
+              (setq target (+ target 1)))
+          (forward-line))
+        target))))
+
+(defun magit-show (commit filename &optional select prefix)
+  "Returns a buffer containing the contents of the file FILENAME, as stored in
+COMMIT.  COMMIT may be one of the following:
+
+- A string with the name of a commit, such as \"head\" or \"dae86e\".  See 'git
+  help revisions' for syntax.
+- The symbol 'index, indicating that you want the version in Git's index or
+  staging area.
+- The symbol 'working, indicating that you want the version in the working
+  directory.  In this case you'll get a buffer visiting the file.  If there's
+  already a buffer visiting that file, you'll get that one.
+
+When called interactively or when SELECT is non-nil, make the buffer active,
+either in another window or (with a prefix argument) in the current window."
+  (interactive (let* ((revision (magit-read-rev "Retrieve file from revision"))
+                      (filename (magit-read-file-from-rev revision)))
+                 (list revision filename t current-prefix-arg)))
+  (if (eq commit 'working)
+      (find-file-noselect filename)
+    (let ((buffer (create-file-buffer (format "%s.%s" filename (replace-regexp-in-string ".*/" "" (prin1-to-string commit t))))))
+      (cond
+       ((eq commit 'index)
+        (let ((checkout-string (magit-git-string "checkout-index"
+                                                 "--temp"
+                                                 filename)))
+          (string-match "^\\(.*\\)\t" checkout-string)
+          (with-current-buffer buffer
+            (let ((tmpname (match-string 1 checkout-string)))
+              (magit-with-silent-modifications
+               (insert-file-contents tmpname nil nil nil t))
+              (delete-file tmpname)))))
+       (t
+        (with-current-buffer buffer
+          (magit-with-silent-modifications
+           (magit-git-insert (list "cat-file" "-p"
+                                   (concat commit ":" filename)))))))
+      (with-current-buffer buffer
+        (let ((buffer-file-name filename))
+          (normal-mode))
+        (goto-char (point-min)))
+      (if select
+          (if prefix
+              (switch-to-buffer buffer)
+            (switch-to-buffer-other-window buffer))
+        buffer))))
+
+(defmacro with-magit-tmp-buffer (var &rest body)
+  (declare (indent 1)
+           (debug (symbolp &rest form)))
+  `(let ((,var (generate-new-buffer magit-tmp-buffer-name)))
+     (unwind-protect
+         (progn ,@body)
+       (kill-buffer ,var))))
+
+(defun magit-apply-diff-item (diff &rest args)
+  (when (zerop magit-diff-context-lines)
+    (setq args (cons "--unidiff-zero" args)))
+  (with-magit-tmp-buffer tmp
+    (magit-insert-diff-item-patch diff tmp)
+    (apply #'magit-run-git-with-input tmp
+           "apply" (append args (list "-")))))
+
+(defun magit-apply-hunk-item* (hunk reverse &rest args)
+  "Apply single hunk or part of a hunk to the index or working file.
+
+This function is the core of magit's stage, unstage, apply, and
+revert operations.  HUNK (or the portion of it selected by the
+region) will be applied to either the index, if \"--cached\" is a
+member of ARGS, or to the working file otherwise."
+  (let ((zero-context (zerop magit-diff-context-lines))
+        (use-region (magit-use-region-p)))
+    (when zero-context
+      (setq args (cons "--unidiff-zero" args)))
+    (when reverse
+      (setq args (cons "--reverse" args)))
+    (when (and use-region zero-context)
+      (error (concat "Not enough context to partially apply hunk.  "
+                     "Use `+' to increase context.")))
+    (with-magit-tmp-buffer tmp
+      (if use-region
+          (magit-insert-hunk-item-region-patch
+           hunk reverse (region-beginning) (region-end) tmp)
+        (magit-insert-hunk-item-patch hunk tmp))
+      (apply #'magit-run-git-with-input tmp
+             "apply" (append args (list "-"))))))
+
+(defun magit-apply-hunk-item (hunk &rest args)
+  (apply #'magit-apply-hunk-item* hunk nil args))
+
+(defun magit-apply-hunk-item-reverse (hunk &rest args)
+  (apply #'magit-apply-hunk-item* hunk t args))
+
+(magit-define-inserter unstaged-changes (title)
+  (let ((magit-hide-diffs t)
+        (magit-current-diff-range (cons 'index 'working)))
+    (let ((magit-diff-options (append '() magit-diff-options)))
+      (magit-git-section 'unstaged title 'magit-wash-raw-diffs
+                         "diff-files"))))
+
+(magit-define-inserter staged-changes (staged no-commit)
+  (let ((magit-current-diff-range (cons "HEAD" 'index)))
+    (when staged
+      (let ((magit-hide-diffs t)
+            (base (if no-commit
+                      (magit-git-string "mktree")
+                    "HEAD")))
+        (let ((magit-diff-options (append '("--cached") magit-diff-options))
+              (magit-ignore-unmerged-raw-diffs t))
+          (magit-git-section 'staged "Staged changes:" 'magit-wash-raw-diffs
+                             "diff-index" "--cached"
+                             base))))))
+
+;;; Logs and Commits
+
+                                        ; Note: making this a plain defcustom would probably let users break
+                                        ; the parser too easily
+(defvar magit-git-log-options
+  (list
+   "--pretty=format:* %h %s"
+   (format "--abbrev=%s" magit-sha1-abbrev-length)))
+                                        ; --decorate=full otherwise some ref prefixes are stripped
+                                        ;  '("--pretty=format:* %H%d %s" "--decorate=full"))
+
+;;
+;; Regexps for parsing ref names
+;;
+;; see the `git-check-ref-format' manpage for details
+
+(defconst magit-ref-nonchars "\000-\037\177 ~^:?*[\\"
+  "Characters specifically disallowed from appearing in Git symbolic refs.
+
+Evaluate (man \"git-check-ref-format\") for details")
+
+(defconst magit-ref-nonslash-re
+  (concat "\\(?:"
+          ;; "no slash-separated component can begin with a dot ." (rule 1)
+          "[^" magit-ref-nonchars "./]"
+          ;; "cannot have two consecutive dots ..  anywhere." (rule 3)
+          "\\.?"
+          "\\)*")
+  "Regexp that matches the non-slash parts of a ref name.
+
+Evaluate (man \"git-check-ref-format\") for details")
+
+(defconst magit-refname-re
+  (concat
+   "\\(?:HEAD\\|"
+
+   "\\(?:tag: \\)?"
+
+   ;; optional non-slash sequence at the beginning
+   magit-ref-nonslash-re
+
+   ;; any number of slash-prefixed sequences
+   "\\(?:"
+   "/"
+   magit-ref-nonslash-re
+   "\\)*"
+
+   "/" ;; "must contain at least one /." (rule 2)
+   magit-ref-nonslash-re
+
+   ;; "cannot end with a slash / nor a dot .." (rule 5)
+   "[^" magit-ref-nonchars "./]"
+
+   "\\)"
+   )
+  "Regexp that matches a git symbolic reference name.
+
+Evaluate (man \"git-check-ref-format\") for details")
+
+(defconst magit-log-oneline-re
+  (concat
+   "^\\([_\\*|/ -.]+\\)?"                          ; graph   (1)
+   "\\(?:"
+   "\\([0-9a-fA-F]+\\)"                            ; sha1    (2)
+   "\\(?:"                                         ; refs    (3)
+   " "
+   "\\("
+   "("
+   magit-refname-re "\\(?:, " magit-refname-re "\\)*"
+   ")"
+   "\\)"
+   "\\)?"
+   "\\)?"
+   " ?\\(.*\\)$"                                   ; msg     (4)
+   ))
+
+(defconst magit-log-longline-re
+  (concat
+   ;; use \0 delimiter (from -z option) to identify commits. this prevents
+   ;; commit messages containing lines like "commit 00000" from polluting the
+   ;; display
+   "\\(?:\\(?:\\`\\|\0\\)"
+   "\\([_\\*|/ -.]+\\)?"                           ; graph   (1)
+   "commit "
+   "\\([0-9a-fA-F]+\\)"                            ; sha1    (2)
+   "\\(?:"                                         ; refs    (3)
+   " "
+   "\\("
+   "("
+   magit-refname-re "\\(?:, " magit-refname-re "\\)*"
+   ")"
+   "\\)"
+   "\\)?"
+   "$\\)?"
+   " ?\\(.*\\)$"                                   ; msg     (4)
+   ))
+
+(defvar magit-present-log-line-function 'magit-present-log-line
+  "The function to use when generating a log line.
+It takes four args: CHART, SHA1, REFS and MESSAGE.  The function
+must return a string which will represent the log line.")
+
+(defun magit-log-get-bisect-state-color (suffix)
+  (if (string= suffix "bad")
+      (list suffix 'magit-log-head-label-bisect-bad)
+    (list suffix 'magit-log-head-label-bisect-good)))
+
+(defun magit-log-get-patches-color (suffix)
+  (list (and (string-match ".+/\\(.+\\)" suffix)
+             (match-string 1 suffix))
+        'magit-log-head-label-patches))
+
+(defvar magit-log-remotes-color-hook nil)
+
+(defun magit-log-get-remotes-color (suffix)
+  (or
+   (run-hook-with-args-until-success
+    'magit-log-remotes-color-hook suffix)
+   (list suffix 'magit-log-head-label-remote)))
+
+(defvar magit-refs-namespaces
+  '(("tags" . magit-log-head-label-tags)
+    ("remotes" magit-log-get-remotes-color)
+    ("heads" . magit-log-head-label-local)
+    ("patches" magit-log-get-patches-color)
+    ("bisect" magit-log-get-bisect-state-color)))
+
+(defun magit-ref-get-label-color (r)
+  (let ((uninteresting (loop for re in magit-uninteresting-refs
+                             thereis (string-match re r))))
+    (if uninteresting (list nil nil)
+      (let* ((ref-re "\\(?:tag: \\)?refs/\\(?:\\([^/]+\\)/\\)?\\(.+\\)")
+             (label (and (string-match ref-re r)
+                         (match-string 2 r)))
+             (res (let ((colorizer
+                         (cdr (assoc (match-string 1 r)
+                                     magit-refs-namespaces))))
+                    (cond ((null colorizer)
+                           (list r 'magit-log-head-label-default))
+                          ((symbolp colorizer)
+                           (list label colorizer))
+                          ((listp colorizer)
+                           (funcall (car colorizer)
+                                    (match-string 2 r)))
+                          (t
+                           (list r 'magit-log-head-label-default))))))
+        res))))
+
+(defun magit-present-log-line (graph sha1 refs message)
+  "The default log line generator."
+  (let ((string-refs
+         (when refs
+           (let ((colored-labels
+                  (delete nil
+                          (mapcar (lambda (r)
+                                    (destructuring-bind (label face)
+                                        (magit-ref-get-label-color r)
+                                      (and label
+                                           (propertize label 'face face))))
+                                  refs))))
+             (concat
+              (mapconcat 'identity colored-labels " ")
+              " ")))))
+
+    (concat
+     (if sha1
+         (propertize sha1 'face 'magit-log-sha1)
+       (insert-char ? magit-sha1-abbrev-length))
+     " "
+     (when graph
+       (propertize graph 'face 'magit-log-graph))
+     string-refs
+     (when message
+       (propertize message 'face 'magit-log-message)))))
+
+(defvar magit-log-count ()
+  "Internal var used to count the number of logs actually added in a buffer.")
+
+(defmacro magit-create-log-buffer-sections (&rest body)
+  "Empty current buffer of text and magit's section, and then evaluate BODY.
+
+if the number of logs inserted in the buffer is `magit-log-cutoff-length'
+insert a line to tell how to insert more of them"
+  (declare (indent 0))
+  `(let ((magit-log-count 0) (inhibit-read-only t))
+     (magit-create-buffer-sections
+       (magit-with-section 'log nil
+         ,@body
+         (if (= magit-log-count magit-log-cutoff-length)
+             (magit-with-section "longer"  'longer
+               (insert "type \"e\" to show more logs\n")))))))
+
+(defun magit-wash-log-line (style)
+  (beginning-of-line)
+  (let ((line-re (cond ((eq style 'long) magit-log-longline-re)
+                       (t magit-log-oneline-re))))
+    (cond
+     ((looking-at line-re)
+      (let ((chart (match-string 1))
+            (sha1 (match-string 2))
+            (msg (match-string 4))
+            (refs (when (match-string 3)
+                    (delq nil
+                          (mapcar
+                           (lambda (s)
+                             (and (not
+                                   (or (string= s "tag:")
+                                       (string= s "HEAD"))) ; as of 1.6.6
+                                  s))
+                           (split-string (match-string 3) "[(), ]" t))))))
+        (delete-region (point-at-bol) (point-at-eol))
+        (insert (funcall magit-present-log-line-function chart sha1 refs msg))
+        (goto-char (point-at-bol))
+        (if sha1
+            (magit-with-section sha1 'commit
+              (when magit-log-count (setq magit-log-count (1+ magit-log-count)))
+              (magit-set-section-info sha1)
+              (forward-line))
+          (forward-line))))
+     (t
+      (forward-line)))
+    t))
+
+(defun magit-wash-log (&optional style)
+  (let ((magit-old-top-section nil))
+    (magit-wash-sequence (apply-partially 'magit-wash-log-line style))))
+
+(defvar magit-currently-shown-commit nil)
+
+(defun magit-wash-commit ()
+  (let ((magit-current-diff-range))
+    (when (looking-at "^commit \\([0-9a-fA-F]\\{40\\}\\)")
+      (setq magit-current-diff-range (match-string 1))
+      (add-text-properties (match-beginning 1) (match-end 1)
+                           '(face magit-log-sha1)))
+    (cond
+     ((search-forward-regexp "^Merge: \\([0-9a-fA-F]+\\) \\([0-9a-fA-F]+\\)$" nil t)
+      (setq magit-current-diff-range (cons (cons (match-string 1)
+                                                 (match-string 2))
+                                           magit-current-diff-range))
+      (let ((first (magit-set-section nil 'commit (match-beginning 1) (match-end 1)))
+            (second (magit-set-section nil 'commit (match-beginning 2) (match-end 2))))
+        (magit-set-section-info (match-string 1) first)
+        (magit-set-section-info (match-string 2) second))
+      (make-commit-button (match-beginning 1) (match-end 1))
+      (make-commit-button (match-beginning 2) (match-end 2)))
+     (t
+      (setq magit-current-diff-range (cons (concat magit-current-diff-range "^")
+                                           magit-current-diff-range))))
+    (search-forward-regexp "^$")
+    (while (and
+            (search-forward-regexp "\\(\\b[0-9a-fA-F]\\{4,40\\}\\b\\)\\|\\(^diff\\)" nil 'noerror)
+            (not (match-string 2)))
+      (let ((sha1 (match-string 1))
+            (start (match-beginning 1))
+            (end (match-end 1)))
+        (when (string-equal "commit" (magit-git-string "cat-file" "-t" sha1))
+          (make-commit-button start end)
+          (let ((section (magit-set-section sha1 'commit start end)))
+            (magit-set-section-info sha1 section)))))
+    (beginning-of-line)
+    (when (looking-at "^diff")
+      (magit-wash-diffs))
+    (goto-char (point-max))
+    (insert "\n")
+    (if magit-back-navigation-history
+        (magit-with-section "[back]" 'button
+          (insert-text-button "[back]"
+                              'help-echo "Previous commit"
+                              'action 'magit-show-commit-backward
+                              'follow-link t
+                              'mouse-face 'magit-item-highlight)))
+    (insert " ")
+    (if magit-forward-navigation-history
+        (magit-with-section "[forward]" 'button
+          (insert-text-button "[forward]"
+                              'help-echo "Next commit"
+                              'action 'magit-show-commit-forward
+                              'follow-link t
+                              'mouse-face 'magit-item-highlight)))))
+
+(defun make-commit-button (start end)
+  (make-text-button start end
+                    'help-echo "Visit commit"
+                    'action (lambda (button)
+                              (save-excursion
+                                (goto-char button)
+                                (magit-visit-item)))
+                    'follow-link t
+                    'mouse-face 'magit-item-highlight
+                    'face 'magit-log-sha1))
+
+(defun magit-refresh-commit-buffer (commit)
+  (magit-configure-have-abbrev)
+  (magit-configure-have-decorate)
+  (magit-create-buffer-sections
+    (apply #'magit-git-section nil nil
+           'magit-wash-commit
+           "log"
+           "--max-count=1"
+           "--pretty=medium"
+           `(,@(if magit-have-abbrev (list "--no-abbrev-commit"))
+             ,@(if magit-have-decorate (list "--decorate=full"))
+             "--cc"
+             "-p" ,commit))))
+
+(define-derived-mode magit-commit-mode magit-mode "Magit"
+  "Mode to view a git commit.
+
+\\{magit-commit-mode-map}"
+  :group 'magit)
+
+(defvar magit-commit-buffer-name "*magit-commit*"
+  "Buffer name for displaying commit log messages.")
+
+(defun magit-show-commit (commit &optional scroll inhibit-history select)
+  "Show information about a commit in the buffer named by
+`magit-commit-buffer-name'.  COMMIT can be any valid name for a commit
+in the current Git repository.
+
+When called interactively or when SELECT is non-nil, switch to
+the commit buffer using `pop-to-buffer'.
+
+Unless INHIBIT-HISTORY is non-nil, the commit currently shown
+will be pushed onto `magit-back-navigation-history' and
+`magit-forward-navigation-history' will be cleared.
+
+Noninteractively, if the commit is already displayed and SCROLL
+is provided, call SCROLL's function definition in the commit
+window.  (`scroll-up' and `scroll-down' are typically passed in
+for this argument.)"
+  (interactive (list (magit-read-rev "Show commit (hash or ref)")
+                     nil nil t))
+  (when (magit-section-p commit)
+    (setq commit (magit-section-info commit)))
+  (unless (eql 0 (magit-git-exit-code "cat-file" "commit" commit))
+    (error "%s is not a commit" commit))
+  (let ((dir default-directory)
+        (buf (get-buffer-create magit-commit-buffer-name)))
+    (cond
+     ((and (equal magit-currently-shown-commit commit)
+           ;; if it's empty then the buffer was killed
+           (with-current-buffer buf
+             (> (length (buffer-string)) 1)))
+      (let ((win (get-buffer-window buf)))
+        (cond ((not win)
+               (display-buffer buf))
+              (scroll
+               (with-selected-window win
+                 (funcall scroll))))))
+     (commit
+      (display-buffer buf)
+      (with-current-buffer buf
+        (unless inhibit-history
+          (push (cons default-directory magit-currently-shown-commit)
+                magit-back-navigation-history)
+          (setq magit-forward-navigation-history nil))
+        (setq magit-currently-shown-commit commit)
+        (goto-char (point-min))
+        (magit-mode-init dir 'magit-commit-mode
+                         #'magit-refresh-commit-buffer commit))))
+    (if select
+        (pop-to-buffer buf))))
+
+(defun magit-show-commit-backward (&optional ignored)
+  ;; Ignore argument passed by push-button
+  "Show the commit at the head of `magit-back-navigation-history in
+`magit-commit-buffer-name`."
+  (interactive)
+  (with-current-buffer magit-commit-buffer-name
+    (unless magit-back-navigation-history
+      (error "No previous commit."))
+    (let ((histitem (pop magit-back-navigation-history)))
+      (push (cons default-directory magit-currently-shown-commit)
+            magit-forward-navigation-history)
+      (setq default-directory (car histitem))
+      (magit-show-commit (cdr histitem) nil 'inhibit-history))))
+
+(defun magit-show-commit-forward (&optional ignored)
+  ;; Ignore argument passed by push-button
+  "Show the commit at the head of `magit-forward-navigation-history in
+`magit-commit-buffer-name`."
+  (interactive)
+  (with-current-buffer magit-commit-buffer-name
+    (unless magit-forward-navigation-history
+      (error "No next commit."))
+    (let ((histitem (pop magit-forward-navigation-history)))
+      (push (cons default-directory magit-currently-shown-commit)
+            magit-back-navigation-history)
+      (setq default-directory (car histitem))
+      (magit-show-commit (cdr histitem) nil 'inhibit-history))))
+
+(defvar magit-marked-commit nil)
+
+(defvar magit-mark-overlay nil)
+(make-variable-buffer-local 'magit-mark-overlay)
+(put 'magit-mark-overlay 'permanent-local t)
+
+(defun magit-refresh-marked-commits ()
+  (magit-for-all-buffers #'magit-refresh-marked-commits-in-buffer))
+
+(defun magit-refresh-marked-commits-in-buffer ()
+  (if (not magit-mark-overlay)
+      (let ((ov (make-overlay 1 1)))
+        (overlay-put ov 'face 'magit-item-mark)
+        (setq magit-mark-overlay ov)))
+  (delete-overlay magit-mark-overlay)
+  (magit-for-all-sections
+   (lambda (section)
+     (when (and (eq (magit-section-type section) 'commit)
+                (equal (magit-section-info section)
+                       magit-marked-commit))
+       (move-overlay magit-mark-overlay
+                     (magit-section-beginning section)
+                     (magit-section-end section)
+                     (current-buffer))))))
+
+(defun magit-set-marked-commit (commit)
+  (setq magit-marked-commit commit)
+  (magit-refresh-marked-commits))
+
+(defun magit-marked-commit ()
+  (or magit-marked-commit
+      (error "No commit marked")))
+
+(defun magit-remote-branch-name (remote branch)
+  "Get the name of the branch BRANCH on remote REMOTE"
+  (if (string= remote ".")
+      branch
+    (concat remote "/" branch)))
+
+(magit-define-inserter unpulled-commits (remote branch)
+  (when remote
+    (apply #'magit-git-section
+           'unpulled "Unpulled commits:" 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    (format "HEAD..%s" (magit-remote-branch-name remote branch)))))))
+
+(magit-define-inserter unpushed-commits (remote branch)
+  (when remote
+    (apply #'magit-git-section
+           'unpushed "Unpushed commits:" 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    (format "%s..HEAD" (magit-remote-branch-name remote branch)))))))
+
+(defun magit-remote-branch-for (local-branch &optional fully-qualified-name)
+  "Guess the remote branch name that LOCAL-BRANCH is tracking.
+Gives a fully qualified name (e.g., refs/remotes/origin/master) if
+FULLY-QUALIFIED-NAME is non-nil."
+  (let ((merge (magit-get "branch" local-branch "merge")))
+    (save-match-data
+      (if (and merge (string-match "^refs/heads/\\(.+\\)" merge))
+          (concat (if fully-qualified-name
+                      (let ((remote-name (magit-get "branch" local-branch "remote")))
+                        (if (string= "." remote-name)
+                            "refs/heads/"
+                          (concat "refs/remotes/" remote-name "/"))))
+                  (match-string 1 merge))))))
+
+;;; Status
+
+(defvar magit-remote-string-hook nil)
+
+(defun magit-remote-string (remote remote-branch remote-rebase)
+  (cond
+   ((string= "." remote)
+    (concat
+     (when remote-rebase "onto ")
+     "branch "
+     (propertize remote-branch 'face 'magit-branch)))
+   (remote
+    (concat
+     (when remote-rebase "onto ")
+     (propertize remote-branch 'face 'magit-branch)
+     " @ "
+     remote
+     " ("
+     (magit-get "remote" remote "url")
+     ")"))
+   (t
+    (run-hook-with-args-until-success 'magit-remote-string-hook))))
+
+(declare-function magit--bisect-info-for-status "magit-bisect" (branch))
+
+(defun magit-refresh-status ()
+  (magit-create-buffer-sections
+    (magit-with-section 'status nil
+      (let* ((branch (magit-get-current-branch))
+             (remote (and branch (magit-get "branch" branch "remote")))
+             (remote-rebase (and branch (magit-get-boolean "branch" branch "rebase")))
+             (remote-branch (or (and branch (magit-remote-branch-for branch)) branch))
+             (remote-string (magit-remote-string remote remote-branch remote-rebase))
+             (head (magit-git-string
+                    "log"
+                    "--max-count=1"
+                    "--abbrev-commit"
+                    (format "--abbrev=%s" magit-sha1-abbrev-length)
+                    "--pretty=oneline"))
+             (no-commit (not head)))
+        (when remote-string
+          (insert "Remote:   " remote-string "\n"))
+        (insert (format "Local:    %s %s\n"
+                        (propertize (magit--bisect-info-for-status branch)
+                                    'face 'magit-branch)
+                        (abbreviate-file-name default-directory)))
+        (insert (format "Head:     %s\n"
+                        (if no-commit "nothing commited (yet)" head)))
+        (let ((merge-heads (magit-file-lines (concat (magit-git-dir)
+                                                     "MERGE_HEAD"))))
+          (if merge-heads
+              (insert (format "Merging:   %s\n"
+                              (mapconcat 'identity
+                                         (mapcar 'magit-name-rev merge-heads)
+                                         ", ")))))
+        (let ((rebase (magit-rebase-info)))
+          (if rebase
+              (insert (apply 'format "Rebasing: onto %s (%s of %s); Press \"R\" to Abort, Skip, or Continue\n" rebase))))
+        (insert "\n")
+        (magit-git-exit-code "update-index" "--refresh")
+        (magit-insert-stashes)
+        (magit-insert-untracked-files)
+        (magit-insert-pending-changes)
+        (magit-insert-pending-commits)
+        (magit-insert-unpulled-commits remote remote-branch)
+        (let ((staged (or no-commit (magit-anything-staged-p))))
+          (magit-insert-unstaged-changes
+           (if staged "Unstaged changes:" "Changes:"))
+          (magit-insert-staged-changes staged no-commit))
+        (magit-insert-unpushed-commits remote remote-branch)
+        (run-hooks 'magit-refresh-status-hook)))))
+
+(defun magit-init (dir)
+  "Initialize git repository in the DIR directory."
+  (interactive (list (read-directory-name "Directory for Git repository: ")))
+  (let* ((dir (file-name-as-directory (expand-file-name dir)))
+         (topdir (magit-get-top-dir dir)))
+    (when (or (not topdir)
+              (yes-or-no-p
+               (format
+                (if (string-equal topdir dir)
+                    "There is already a Git repository in %s. Reinitialize? "
+                  "There is a Git repository in %s. Create another in %s? ")
+                topdir dir)))
+      (unless (file-directory-p dir)
+        (and (y-or-n-p (format "Directory %s does not exists.  Create it? " dir))
+             (make-directory dir)))
+      (let ((default-directory dir))
+        (magit-run* (list magit-git-executable "init"))))))
+
+(define-derived-mode magit-status-mode magit-mode "Magit"
+  "Mode for looking at git status.
+
+\\{magit-status-mode-map}"
+  :group 'magit)
+
+(defvar magit-default-directory nil)
+
+(defun magit-save-some-buffers (&optional msg pred)
+  "Save some buffers if variable `magit-save-some-buffers' is non-nil.
+If variable `magit-save-some-buffers' is set to 'dontask then
+don't ask the user before saving the buffers, just go ahead and
+do it.
+
+Optional argument MSG is displayed in the minibuffer if variable
+`magit-save-some-buffers' is nil.
+
+Optional second argument PRED determines which buffers are considered:
+If PRED is nil, all the file-visiting buffers are considered.
+If PRED is t, then certain non-file buffers will also be considered.
+If PRED is a zero-argument function, it indicates for each buffer whether
+to consider it or not when called with that buffer current."
+  (interactive)
+  (let ((predicate-function (or pred magit-save-some-buffers-predicate))
+        (magit-default-directory default-directory))
+    (if magit-save-some-buffers
+        (save-some-buffers
+         (eq magit-save-some-buffers 'dontask)
+         predicate-function)
+      (when msg
+        (message msg)))))
+
+(defun magit-save-buffers-predicate-all ()
+  "Prompt to save all buffers with unsaved changes"
+  t)
+
+(defun magit-save-buffers-predicate-tree-only ()
+  "Only prompt to save buffers which are within the current git project (as
+  determined by the dir passed to `magit-status'."
+  (and buffer-file-name
+       (string= (magit-get-top-dir magit-default-directory)
+                (magit-get-top-dir (file-name-directory buffer-file-name)))))
+
+;;;###autoload
+(defun magit-status (dir)
+  "Open a Magit status buffer for the Git repository containing
+DIR.  If DIR is not within a Git repository, offer to create a
+Git repository in DIR.
+
+Interactively, a prefix argument means to ask the user which Git
+repository to use even if `default-directory' is under Git control.
+Two prefix arguments means to ignore `magit-repo-dirs' when asking for
+user input."
+  (interactive (list (if current-prefix-arg
+                         (magit-read-top-dir
+                          (> (prefix-numeric-value current-prefix-arg)
+                             4))
+                       (or (magit-get-top-dir default-directory)
+                           (magit-read-top-dir nil)))))
+  (magit-save-some-buffers)
+  (let ((topdir (magit-get-top-dir dir)))
+    (unless topdir
+      (when (y-or-n-p (format "There is no Git repository in %S.  Create one? "
+                              dir))
+        (magit-init dir)
+        (setq topdir (magit-get-top-dir dir))))
+    (when topdir
+      (let ((buf (or (magit-find-status-buffer topdir)
+                     (generate-new-buffer
+                      (concat "*magit: "
+                              (file-name-nondirectory
+                               (directory-file-name topdir)) "*")))))
+        (funcall magit-status-buffer-switch-function buf)
+        (magit-mode-init topdir 'magit-status-mode #'magit-refresh-status)))))
+
+(magit-define-command automatic-merge (revision)
+  "Merge REVISION into the current 'HEAD'; commit unless merge fails.
+\('git merge REVISION')."
+  (interactive (list (magit-read-rev "Merge" (magit-guess-branch))))
+  (if revision
+      (magit-run-git "merge" (magit-rev-to-git revision))))
+
+(magit-define-command manual-merge (revision)
+  "Merge REVISION into the current 'HEAD'; commit unless merge fails.
+\('git merge REVISION')."
+  (interactive (list (magit-read-rev "Merge" (magit-guess-branch))))
+  (when revision
+    (apply 'magit-run-git
+           "merge" "--no-commit"
+           (magit-rev-to-git revision)
+           magit-custom-options)
+    (when (file-exists-p ".git/MERGE_MSG")
+        (magit-log-edit))))
+
+;;; Staging and Unstaging
+
+(defun magit-stage-item (&optional ask)
+  "Add the item at point to the staging area.
+If ASK is set, ask for the file name rather than picking the one
+at point."
+  (interactive "P")
+  (if ask
+      (magit-run-git "add" (read-file-name "File to stage: "))
+    (magit-section-action (item info "stage")
+      ((untracked file)
+       (magit-run-git "add" info))
+      ((untracked)
+       (apply #'magit-run-git "add" "--"
+              (magit-git-lines "ls-files" "--other" "--exclude-standard")))
+      ((unstaged diff hunk)
+       (if (magit-hunk-item-is-conflict-p item)
+           (error (concat "Can't stage individual resolution hunks.  "
+                          "Please stage the whole file.")))
+       (magit-apply-hunk-item item "--cached"))
+      ((unstaged diff)
+       (magit-run-git "add" "-u" (magit-diff-item-file item)))
+      ((staged *)
+       (error "Already staged"))
+      ((diff diff)
+       (save-excursion
+         (magit-goto-parent-section)
+         (magit-stage-item)))
+      ((diff diff hunk)
+       (save-excursion
+         (magit-goto-parent-section)
+         (magit-goto-parent-section)
+         (magit-stage-item)))
+      ((hunk)
+       (error "Can't stage this hunk"))
+      ((diff)
+       (error "Can't stage this diff")))))
+
+(defun magit-unstage-item ()
+  "Remove the item at point from the staging area."
+  (interactive)
+  (magit-section-action (item info "unstage")
+    ((staged diff hunk)
+     (magit-apply-hunk-item-reverse item "--cached"))
+    ((staged diff)
+     (if (eq (car info) 'unmerged)
+         (error "Can't unstage an unmerged file.  Resolve it first"))
+     (if (magit-no-commit-p)
+         (magit-run-git "rm" "--cached" "--" (magit-diff-item-file item))
+       (magit-run-git "reset" "-q" "HEAD" "--" (magit-diff-item-file item))))
+    ((unstaged *)
+     (error "Already unstaged"))
+    ((diff diff)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-unstage-item)))
+    ((diff diff hunk)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-goto-parent-section)
+       (magit-unstage-item)))
+    ((hunk)
+     (error "Can't unstage this hunk"))
+    ((diff)
+     (error "Can't unstage this diff"))))
+
+(defun magit-stage-all (&optional also-untracked-p)
+  "Add all remaining changes in tracked files to staging area.
+With prefix argument, add remaining untracked files as well.
+\('git add -u .' or 'git add .', respectively)."
+  (interactive "P")
+  (if also-untracked-p
+      (magit-run-git "add" ".")
+    (magit-run-git "add" "-u" ".")))
+
+(defun magit-unstage-all ()
+  "Remove all changes from staging area.
+\('git reset --mixed HEAD')."
+  (interactive)
+  (magit-run-git "reset" "HEAD"))
+
+;;; Branches
+
+(defun escape-branch-name (branch)
+  "Escapes branch names to remove problematic characters."
+  (replace-regexp-in-string "[/]" "-" branch))
+
+(defun magit-default-tracking-name-remote-plus-branch
+  (remote branch)
+  "Use the remote name plus a hyphen plus the escaped branch name for tracking branches."
+  (concat remote "-" (escape-branch-name branch)))
+
+(defun magit-default-tracking-name-branch-only
+  (remote branch)
+  "Use just the escaped branch name for tracking branches."
+  (escape-branch-name branch))
+
+(defun magit-get-tracking-name (remote branch)
+  "Given a REMOTE and a BRANCH name, ask the user for a local
+tracking brach name suggesting a sensible default."
+  (when (yes-or-no-p
+         (format "Create local tracking branch for %s? " branch))
+    (let* ((default-name
+             (funcall magit-default-tracking-name-function remote branch))
+           (chosen-name (read-string (format "Call local branch (%s): " default-name)
+                                     nil
+                                     nil
+                                     default-name)))
+      (when (magit-ref-exists-p (concat "refs/heads/" chosen-name))
+        (error "'%s' already exists." chosen-name))
+      chosen-name)))
+
+(defun magit-maybe-create-local-tracking-branch (rev)
+  "Depending on the users wishes, create a tracking branch for
+rev... maybe."
+  (if (string-match "^\\(?:refs/\\)?remotes/\\([^/]+\\)/\\(.+\\)" rev)
+      (let* ((remote (match-string 1 rev))
+             (branch (match-string 2 rev))
+             (tracker-name (magit-get-tracking-name remote branch)))
+        (when tracker-name
+          (magit-run-git "checkout" "-b" tracker-name rev)
+          t))
+    nil))
+
+(magit-define-command checkout (revision)
+  "Switch 'HEAD' to REVISION and update working tree.
+Fails if working tree or staging area contain uncommitted changes.
+If REVISION is a remote branch, offer to create a local tracking branch.
+\('git checkout [-b] REVISION')."
+  (interactive
+   (list (let ((current-branch (magit-get-current-branch))
+               (default (magit-default-rev)))
+           (magit-read-rev "Switch to"
+                           (unless (string= current-branch default)
+                             default)
+                           (if current-branch
+                               (cons (concat "refs/heads/" current-branch "$")
+                                     magit-uninteresting-refs)
+                             magit-uninteresting-refs)))))
+  (if revision
+      (when (not (magit-maybe-create-local-tracking-branch revision))
+        (magit-save-some-buffers)
+        (magit-run-git "checkout" (magit-rev-to-git revision))
+        (magit-update-vc-modeline default-directory))))
+
+(defun magit-read-create-branch-args ()
+  (let* ((cur-branch (magit-get-current-branch))
+         (cur-point (magit-default-rev))
+         (branch (read-string "Create branch: "))
+         (parent (magit-read-rev "Parent"
+                                 (cond
+                                  ((eq magit-create-branch-behaviour 'at-point) cur-point)
+                                  ((eq magit-create-branch-behaviour 'at-head) cur-branch)
+                                  (t cur-branch)))))
+    (list branch parent)))
+
+(magit-define-command create-branch (branch parent)
+  "Switch 'HEAD' to new BRANCH at revision PARENT and update working tree.
+Fails if working tree or staging area contain uncommitted changes.
+\('git checkout -b BRANCH REVISION')."
+  (interactive (magit-read-create-branch-args))
+  (when (and branch (not (string= branch ""))
+             parent)
+    (magit-save-some-buffers)
+    (magit-run-git "checkout" "-b"
+                   branch
+                   (append
+                    magit-custom-options
+                    (magit-rev-to-git parent)))
+    (magit-update-vc-modeline default-directory)))
+
+(defun magit-delete-branch (branch &optional force)
+  "Deletes a branch.
+If the branch is the current one, offers to switch to `master' first.
+With prefix, forces the removal even if it hasn't been merged.
+Works with local or remote branches.
+\('git branch [-d|-D] BRANCH' or 'git push <remote-part-of-BRANCH> :refs/heads/BRANCH')."
+  (interactive (list (magit-read-rev "Branch to delete" (magit-default-rev 'notrim))
+                     current-prefix-arg))
+  (let* ((remote (magit-remote-part-of-branch branch))
+         (is-current (string= branch (magit-get-current-branch)))
+         (args (list "branch"
+                     (if force "-D" "-d")
+                     branch)))
+    (cond
+     (remote
+      (magit-run-git "push" remote (concat ":refs/heads/" (magit-branch-no-remote branch))))
+     (is-current
+      (when (y-or-n-p "Cannot delete current branch. Switch to master first? ")
+          (progn
+            (magit-checkout "master")
+            (apply 'magit-run-git args))
+          (message "The current branch was not deleted.")))
+     (t
+            (apply 'magit-run-git args)))))
+
+(defun magit-move-branch (old new &optional force)
+  "Renames or moves a branch.
+With prefix, forces the move even if NEW already exists.
+\('git branch [-m|-M] OLD NEW')."
+  (interactive (list (magit-read-rev "Old name" (magit-default-rev))
+                     (read-string "New name: ")
+                     current-prefix-arg))
+  (magit-run-git "branch" (if force
+                              "-M"
+                            "-m")
+                 (magit-rev-to-git old) new))
+
+(defun magit-guess-branch ()
+  (magit-section-case (item info)
+    ((branch)
+     (magit-section-info (magit-current-section)))
+    ((wazzup commit)
+     (magit-section-info (magit-section-parent item)))
+    ((commit) (magit-name-rev (substring info 0 magit-sha1-abbrev-length)))
+    ((wazzup) info)))
+
+;;; Remotes
+
+(defun magit-add-remote (remote url)
+  "Adds a remote and fetches it.
+\('git remote add REMOTE URL')."
+  (interactive (list (read-string "Add remote: ")
+                     (read-string "URL: ")))
+  (magit-run-git "remote" "add" "-f" remote url))
+
+(defun magit-remove-remote (remote)
+  "Deletes a remote.
+\('git remote rm REMOTE')."
+  (interactive (list (magit-read-remote "Remote to delete")))
+  (magit-run-git "remote" "rm" remote))
+
+(defun magit-rename-remote (old new)
+  "Renames a remote.
+\('git remote rename OLD NEW')."
+  (interactive (list (magit-read-remote "Old name")
+                     (read-string "New name: ")))
+  (magit-run-git "remote" "rename" old new))
+
+(defun magit-guess-remote ()
+  (magit-section-case (item info)
+    ((branch)
+     (magit-section-info (magit-section-parent item)))
+    ((remote)
+     info)
+    (t
+     (if  (string= info ".")
+         info
+       (magit-get-current-remote)))))
+
+;;; Merging
+
+(defun magit-merge (revision)
+  "Merge REVISION into the current 'HEAD'; leave changes uncommitted.
+With a prefix-arg, the merge will be squashed.
+\('git merge --no-commit [--squash|--no-ff] REVISION')."
+  (interactive
+   (list (magit-read-rev "Merge" (magit-default-rev))))
+  (if revision
+      (apply 'magit-run-git
+             "merge"
+             (magit-rev-to-git revision)
+             magit-custom-options)))
+
+;;; Rebasing
+
+(defun magit-rebase-info ()
+  "Returns a list indicating the state of an in-progress rebase,
+if any."
+  (let ((git-dir (magit-git-dir)))
+    (cond ((file-exists-p (concat git-dir "rebase-merge"))
+           (list
+            ;; The commit we're rebasing onto, i.e. git rebase -i <onto>
+            (magit-name-rev (car (magit-file-lines (concat git-dir "rebase-merge/onto"))))
+
+            ;; How many commits we've gone through
+            (length (magit-file-lines (concat git-dir "rebase-merge/done")))
+
+            ;; How many commits we have in total, without the comments
+            ;; at the end of git-rebase-todo.backup
+            (let ((todo-lines-with-comments (magit-file-lines (concat git-dir "rebase-merge/git-rebase-todo.backup"))))
+              (loop for i in todo-lines-with-comments
+                    until (string= "" i)
+                    count i))))
+          ((and (file-exists-p (concat git-dir "rebase-apply"))
+                (file-exists-p (concat git-dir "rebase-apply/onto")))
+           ;; we might be here because a non-interactive rebase failed: the
+           ;; patches didn't apply cleanly
+           (list
+            ;; The commit we're rebasing onto, i.e. git rebase -i <onto>
+            (magit-name-rev (car (magit-file-lines (concat git-dir "rebase-apply/onto"))))
+
+            ;; How many commits we've gone through
+            (- (string-to-number (car (magit-file-lines (concat git-dir "rebase-apply/next")))) 1)
+
+            ;; How many commits we have in total
+            (string-to-number (car (magit-file-lines (concat git-dir "rebase-apply/last"))))
+            ))
+          (t nil))))
+
+(defun magit-rebase-step ()
+  (interactive)
+  (let ((info (magit-rebase-info)))
+    (if (not info)
+        (let* ((current-branch (magit-get-current-branch))
+               (rev (magit-read-rev "Rebase to"
+                                    (magit-format-ref (magit-remote-branch-for current-branch t))
+                                    (if current-branch
+                                        (cons (concat "refs/heads/" current-branch)
+                                              magit-uninteresting-refs)
+                                      magit-uninteresting-refs))))
+          (if rev
+              (magit-run-git "rebase" (magit-rev-to-git rev))))
+      (let ((cursor-in-echo-area t)
+            (message-log-max nil))
+        (message "Rebase in progress. [A]bort, [S]kip, or [C]ontinue? ")
+        (let ((reply (read-event)))
+          (case reply
+            ((?A ?a)
+             (magit-run-git-async "rebase" "--abort"))
+            ((?S ?s)
+             (magit-run-git-async "rebase" "--skip"))
+            ((?C ?c)
+             (magit-run-git-async "rebase" "--continue"))))))))
+
+;;; Resetting
+
+(magit-define-command reset-head (revision &optional hard)
+  "Switch 'HEAD' to REVISION, keeping prior working tree and staging area.
+Any differences from REVISION become new changes to be committed.
+With prefix argument, all uncommitted changes in working tree
+and staging area are lost.
+\('git reset [--soft|--hard] REVISION')."
+  (interactive (list (magit-read-rev (format "%s head to"
+                                             (if current-prefix-arg
+                                                 "Hard reset"
+                                               "Reset"))
+                                     (or (magit-default-rev)
+                                         "HEAD^"))
+                     current-prefix-arg))
+  (when revision
+    (magit-run-git "reset" (if hard "--hard" "--soft")
+                   (magit-rev-to-git revision))
+    (magit-update-vc-modeline default-directory)))
+
+(magit-define-command reset-head-hard (revision)
+  "Switch 'HEAD' to REVISION, losing all changes.
+Uncomitted changes in both working tree and staging area are lost.
+\('git reset --hard REVISION')."
+  (interactive (list (magit-read-rev (format "Hard reset head to")
+                                     (or (magit-default-rev)
+                                         "HEAD"))))
+  (magit-reset-head revision t))
+
+(magit-define-command reset-working-tree (&optional arg)
+  "Revert working tree and clear changes from staging area.
+\('git reset --hard HEAD').
+
+With a prefix arg, also remove untracked files.  With two prefix args, remove ignored files as well."
+  (interactive "p")
+  (let ((include-untracked (>= arg 4))
+        (include-ignored (>= arg 16)))
+    (when (yes-or-no-p (format "Discard all uncommitted changes%s%s? "
+                               (if include-untracked
+                                   ", untracked files"
+                                 "")
+                               (if include-ignored
+                                   ", ignored files"
+                                 "")))
+      (magit-reset-head-hard "HEAD")
+      (if include-untracked
+          (magit-run-git "clean" "-fd" (if include-ignored
+                                           "-x"
+                                         ""))))))
+
+;;; Rewriting
+
+(defun magit-read-rewrite-info ()
+  (when (file-exists-p (concat (magit-git-dir) "magit-rewrite-info"))
+    (with-temp-buffer
+      (insert-file-contents (concat (magit-git-dir) "magit-rewrite-info"))
+      (goto-char (point-min))
+      (read (current-buffer)))))
+
+(defun magit-write-rewrite-info (info)
+  (with-temp-file (concat (magit-git-dir) "magit-rewrite-info")
+    (prin1 info (current-buffer))
+    (princ "\n" (current-buffer))))
+
+(magit-define-inserter pending-commits ()
+  (let* ((info (magit-read-rewrite-info))
+         (pending (cdr (assq 'pending info))))
+    (when pending
+      (magit-with-section 'pending nil
+        (insert (propertize "Pending commits:\n"
+                            'face 'magit-section-title))
+        (dolist (p pending)
+          (let* ((commit (car p))
+                 (properties (cdr p))
+                 (used (plist-get properties 'used)))
+            (magit-with-section commit 'commit
+              (magit-set-section-info commit)
+              (insert (magit-git-string
+                       "log" "--max-count=1"
+                       (if used
+                           "--pretty=format:. %s"
+                         "--pretty=format:* %s")
+                       commit "--")
+                      "\n")))))
+      (insert "\n"))))
+
+(defun magit-rewrite-set-commit-property (commit prop value)
+  (let* ((info (magit-read-rewrite-info))
+         (pending (cdr (assq 'pending info)))
+         (p (assoc commit pending)))
+    (when p
+      (setf (cdr p) (plist-put (cdr p) prop value))
+      (magit-write-rewrite-info info)
+      (magit-need-refresh))))
+
+(defun magit-rewrite-set-used ()
+  (interactive)
+  (magit-section-action (item info)
+    ((pending commit)
+     (magit-rewrite-set-commit-property info 'used t))))
+
+(defun magit-rewrite-set-unused ()
+  (interactive)
+  (magit-section-action (item info)
+    ((pending commit)
+     (magit-rewrite-set-commit-property info 'used nil))))
+
+(magit-define-inserter pending-changes ()
+  (let* ((info (magit-read-rewrite-info))
+         (orig (cadr (assq 'orig info))))
+    (when orig
+      (let ((magit-hide-diffs t))
+        (magit-git-section 'pending-changes
+                           "Pending changes"
+                           'magit-wash-diffs
+                           "diff" (magit-diff-U-arg) "-R" orig)))))
+
+(defun magit-rewrite-start (from &optional onto)
+  (interactive (list (magit-read-rev "Rewrite from" (magit-default-rev))))
+  (or (magit-everything-clean-p)
+      (error "You have uncommitted changes"))
+  (or (not (magit-read-rewrite-info))
+      (error "Rewrite in progress"))
+  (let* ((orig (magit-rev-parse "HEAD"))
+         (base
+          (if
+              (or
+               (eq magit-rewrite-inclusive t)
+               (and
+                (eq magit-rewrite-inclusive 'ask)
+                (y-or-n-p "Include selected revision in rewrite? ")))
+              (or
+               (car (magit-commit-parents from))
+               (error "Can't rewrite a parentless commit."))
+            from))
+         (pending (magit-git-lines "rev-list" (concat base ".."))))
+    (magit-write-rewrite-info `((orig ,orig)
+                                (pending ,@(mapcar #'list pending))))
+    (magit-run-git "reset" "--hard" base)))
+
+(defun magit-rewrite-stop (&optional noconfirm)
+  (interactive)
+  (let* ((info (magit-read-rewrite-info)))
+    (or info
+        (error "No rewrite in progress"))
+    (when (or noconfirm
+              (yes-or-no-p "Stop rewrite? "))
+      (magit-write-rewrite-info nil)
+      (magit-refresh))))
+
+(defun magit-rewrite-abort ()
+  (interactive)
+  (let* ((info (magit-read-rewrite-info))
+         (orig (cadr (assq 'orig info))))
+    (or info
+        (error "No rewrite in progress"))
+    (or (magit-everything-clean-p)
+        (error "You have uncommitted changes"))
+    (when (yes-or-no-p "Abort rewrite? ")
+      (magit-write-rewrite-info nil)
+      (magit-run-git "reset" "--hard" orig))))
+
+(defun magit-rewrite-finish ()
+  (interactive)
+  (magit-with-refresh
+    (magit-rewrite-finish-step t)))
+
+(defun magit-rewrite-finish-step (first-p)
+  (let ((info (magit-read-rewrite-info)))
+    (or info
+        (error "No rewrite in progress"))
+    (let* ((pending (cdr (assq 'pending info)))
+           (first-unused
+            (let ((rpend (reverse pending)))
+              (while (and rpend (plist-get (cdr (car rpend)) 'used))
+                (setq rpend (cdr rpend)))
+              (car rpend)))
+           (commit (car first-unused)))
+      (cond ((not first-unused)
+             (magit-rewrite-stop t))
+            ((magit-apply-commit commit t (not first-p))
+             (magit-rewrite-set-commit-property commit 'used t)
+             (magit-rewrite-finish-step nil))))))
+
+;;; Updating, pull, and push
+
+(magit-define-command fetch (remote)
+  "Fetch from REMOTE."
+  (interactive (list (magit-read-remote)))
+  (apply 'magit-run-git-async "fetch" remote magit-custom-options))
+
+(magit-define-command fetch-current ()
+  "Run fetch for default remote.
+
+If there is no default remote, ask for one."
+  (interactive)
+  (magit-fetch (or (magit-get-current-remote)
+                   (magit-read-remote))))
+
+(magit-define-command remote-update ()
+  "Update all remotes."
+  (interactive)
+  (apply 'magit-run-git-async "remote" "update" magit-custom-options))
+
+(magit-define-command pull ()
+  "Run git pull against the current remote."
+  (interactive)
+  (let* ((branch (magit-get-current-branch))
+         (branch-remote (magit-get-remote branch))
+         (config-branch (and branch (magit-get "branch" branch "merge")))
+         (merge-branch (or (and config-branch (not current-prefix-arg))
+                           (magit-read-remote-branch
+                            branch-remote (format "Pull from: ")))))
+    (when (and branch (not config-branch))
+      (magit-set branch-remote "branch" branch "remote")
+      (magit-set (format "refs/heads/%s" merge-branch)
+                 "branch" branch "merge"))
+    (apply 'magit-run-git-async "pull" "-v" magit-custom-options)))
+
+(eval-when-compile (require 'eshell))
+
+(defun magit-parse-arguments (command)
+  (require 'eshell)
+  (with-temp-buffer
+    (insert command)
+    (mapcar 'eval (eshell-parse-arguments (point-min) (point-max)))))
+
+(defun magit-shell-command (command)
+  "Perform arbitrary shell COMMAND."
+  (interactive "sCommand: ")
+  (let ((args (magit-parse-arguments command))
+        (magit-process-popup-time 0))
+    (magit-run* args nil nil nil t)))
+
+(defvar magit-git-command-history nil)
+
+(defun magit-git-command (command)
+  "Perform arbitrary Git COMMAND.
+
+Similar to `magit-shell-command', but involves slightly less
+typing and automatically refreshes the status buffer."
+  (interactive
+   (list (read-string "Run git like this: " nil 'magit-git-command-history)))
+  (require 'pcomplete)
+  (let ((args (magit-parse-arguments command))
+        (magit-process-popup-time 0))
+    (magit-with-refresh
+      (magit-run* (append (cons magit-git-executable
+                                magit-git-standard-options)
+                          args)
+                  nil nil nil t))))
+
+(magit-define-command push-tags ()
+  "Push tags."
+  (interactive)
+  (magit-run-git-async "push" "--tags"))
+
+(magit-define-command push ()
+  "Push the current branch to a remote repository.
+
+With no prefix argument, ask `magit-get-remote' what remote to
+use for this branch.
+
+With a prefix arg \(e.g., \\[universal-argument] \\[magit-push]), \
+ask user instead.
+
+With \\[universal-argument] \\[universal-argument] as prefix, \
+also prompt user for the remote branch;
+otherwise, try to use the branch.<name>.merge git-config(1)
+option, falling back to something hairy if that is unset."
+  (interactive)
+  (let* ((branch (or (magit-get-current-branch)
+                     (error "Don't push a detached head.  That's gross")))
+         (branch-remote (magit-get-remote branch))
+         (push-remote (if (or current-prefix-arg
+                              (not branch-remote))
+                          (magit-read-remote (format "Push %s to remote"
+                                                     branch)
+                                             branch-remote)
+                        branch-remote))
+         (ref-branch (or (and (>= (prefix-numeric-value current-prefix-arg) 16)
+                              (magit-read-remote-branch
+                               push-remote (format "Push %s as branch" branch)))
+                         (magit-get "branch" branch "merge"))))
+    (if (and (not ref-branch)
+             (eq magit-set-upstream-on-push 'refuse))
+        (error "Not pushing since no upstream has been set.")
+      (let ((set-upstream-on-push (and (not ref-branch)
+                                       (or (eq magit-set-upstream-on-push 'dontask)
+                                           (and (eq magit-set-upstream-on-push t)
+                                                (yes-or-no-p "Set upstream while pushing? "))))))
+        (if (and (not branch-remote)
+                 (not current-prefix-arg))
+            (magit-set push-remote "branch" branch "remote"))
+        (apply 'magit-run-git-async "push" "-v" push-remote
+               (if ref-branch
+                   (format "%s:%s" branch ref-branch)
+                 branch)
+               (if set-upstream-on-push
+                   (cons "--set-upstream" magit-custom-options)
+                 magit-custom-options))
+        ;; Although git will automatically set up the remote,
+        ;; it doesn't set up the branch to merge (at least as of Git 1.6.6.1),
+        ;; so we have to do that manually.
+        (unless ref-branch
+          (magit-set (concat "refs/heads/" branch) "branch" branch "merge"))))))
+
+;;; Log edit mode
+
+(defvar magit-log-edit-buffer-name "*magit-edit-log*"
+  "Buffer name for composing commit messages.")
+
+(defvar magit-log-edit-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-c") 'magit-log-edit-commit)
+    (define-key map (kbd "C-x #") 'magit-log-edit-commit)
+    (define-key map (kbd "C-c C-a") 'magit-log-edit-toggle-amending)
+    (define-key map (kbd "C-c C-s") 'magit-log-edit-toggle-signoff)
+    (define-key map (kbd "C-c C-t") 'magit-log-edit-toggle-author)
+    (define-key map (kbd "C-c C-e") 'magit-log-edit-toggle-allow-empty)
+    (define-key map (kbd "M-p") 'log-edit-previous-comment)
+    (define-key map (kbd "M-n") 'log-edit-next-comment)
+    (define-key map (kbd "C-c C-k") 'magit-log-edit-cancel-log-message)
+    (define-key map (kbd "C-c C-]") 'magit-log-edit-cancel-log-message)
+    (define-key map (kbd "C-x C-s") (lambda ()
+                                      (interactive)
+                                      (message "Not saved. Use C-c C-c to finalize this commit message.")))
+    map))
+
+(defvar magit-pre-log-edit-window-configuration nil)
+
+(define-derived-mode magit-log-edit-mode text-mode "Magit Log Edit"
+  ;; Recognize changelog-style paragraphs
+  (set (make-local-variable 'paragraph-start)
+       (concat paragraph-start "\\|*\\|(")))
+
+(defun magit-log-edit-cleanup ()
+  (save-excursion
+    (goto-char (point-min))
+    (goto-char (point-min))
+    (if (re-search-forward "[ \t\n]*\\'" nil t)
+        (replace-match "\n" nil nil))))
+
+(defun magit-log-edit-append (str)
+  (with-current-buffer (get-buffer-create magit-log-edit-buffer-name)
+    (goto-char (point-max))
+    (insert str "\n")))
+
+(defconst magit-log-header-end "-- End of Magit header --\n")
+
+(defun magit-log-edit-get-fields ()
+  (let ((buf (get-buffer magit-log-edit-buffer-name))
+        (result nil))
+    (if buf
+        (with-current-buffer buf
+          (goto-char (point-min))
+          (while (looking-at "^\\([A-Za-z0-9-_]+\\): *\\(.+\\)?$")
+            (setq result (acons (intern (downcase (match-string 1)))
+                                (read (or (match-string 2) "nil"))
+                                result))
+            (forward-line))
+          (if (not (looking-at (regexp-quote magit-log-header-end)))
+              (setq result nil))))
+    (nreverse result)))
+
+(defun magit-log-edit-set-fields (fields)
+  (let ((buf (get-buffer-create magit-log-edit-buffer-name)))
+    (with-current-buffer buf
+      (goto-char (point-min))
+      (if (search-forward-regexp (format "^\\([A-Za-z0-9-_]+:.*\n\\)*%s"
+                                         (regexp-quote magit-log-header-end))
+                                 nil t)
+          (delete-region (match-beginning 0) (match-end 0)))
+      (goto-char (point-min))
+      (when fields
+        (while fields
+          (insert (capitalize (symbol-name (caar fields))) ": "
+                  (prin1-to-string (cdar fields)) "\n")
+          (setq fields (cdr fields)))
+        (insert magit-log-header-end)))))
+
+(defun magit-log-edit-set-field (name value)
+  (let* ((fields (magit-log-edit-get-fields))
+         (cell (assq name fields)))
+    (cond (cell
+           (if value
+               (rplacd cell value)
+             (setq fields (delq cell fields))))
+          (t
+           (if value
+               (setq fields (append fields (list (cons name value)))))))
+    (magit-log-edit-set-fields fields)))
+
+(defun magit-log-edit-get-field (name)
+  (cdr (assq name (magit-log-edit-get-fields))))
+
+(defun magit-log-edit-toggle-field (name default)
+  "Toggle the log-edit field named NAME.
+If it's currently unset, set it to DEFAULT (t or nil).
+
+Return nil if the field is toggled off, and non-nil if it's
+toggled on.  When it's toggled on for the first time, return
+'first."
+  (let* ((fields (magit-log-edit-get-fields))
+         (cell (assq name fields)) yesp)
+    (if cell
+        (progn
+          (setq yesp (equal (cdr cell) "yes"))
+          (rplacd cell (if yesp "no" "yes")))
+      (setq fields (acons name (if default "yes" "no") fields))
+      (setq yesp (if default 'first)))
+    (magit-log-edit-set-fields fields)
+    yesp))
+
+(defun magit-log-edit-toggle-input (name default)
+  "Toggle the log-edit input named NAME.
+If it's currently unset, set it to DEFAULT (a string). If it is
+set remove it.
+
+Return nil if the input is toggled off, and its valud if it's
+toggled on."
+  (let* ((fields (magit-log-edit-get-fields))
+         (cell (assq name fields))
+         result)
+    (if cell
+        (progn
+          (setq fields (assq-delete-all name fields)
+                result (cdr cell)))
+      (setq fields (acons name default fields)))
+    (magit-log-edit-set-fields fields)
+    result))
+
+(defun magit-log-edit-setup-author-env (author)
+  "Set GIT_AUTHOR_* variables from AUTHOR spec.
+If AUTHOR is nil, honor default values from
+environment (potentially empty)."
+  (when author
+    ;; XXX - this is a bit strict, probably.
+    (or (string-match "\\(.*\\) <\\(.*\\)>\\(?:,\\s-*\\(.+\\)\\)?" author)
+        (error "Can't parse author string"))
+    ;; Shucks, setenv destroys the match data.
+    (let ((name (match-string 1 author))
+          (email (match-string 2 author))
+          (date  (match-string 3 author)))
+      (make-local-variable 'process-environment)
+      (setenv "GIT_AUTHOR_NAME" name)
+      (setenv "GIT_AUTHOR_EMAIL" email)
+      (if date
+          (setenv "GIT_AUTHOR_DATE" date)))))
+
+(defun magit-log-edit-push-to-comment-ring (comment)
+  (when (or (ring-empty-p log-edit-comment-ring)
+            (not (equal comment (ring-ref log-edit-comment-ring 0))))
+    (ring-insert log-edit-comment-ring comment)))
+
+(defun magit-log-edit-commit ()
+  "Finish edits and create new commit object.
+\('git commit ...')"
+  (interactive)
+  (let* ((fields (magit-log-edit-get-fields))
+         (amend (equal (cdr (assq 'amend fields)) "yes"))
+         (allow-empty (equal (cdr (assq 'allow-empty fields)) "yes"))
+         (commit-all (equal (cdr (assq 'commit-all fields)) "yes"))
+         (sign-off-field (assq 'sign-off fields))
+         (sign-off (if sign-off-field
+                       (equal (cdr sign-off-field) "yes")
+                     magit-commit-signoff))
+         (tag-rev (cdr (assq 'tag-rev fields)))
+         (tag-name (cdr (assq 'tag-name fields)))
+         (author (cdr (assq 'author fields)))
+         (tag-options (cdr (assq 'tag-options fields))))
+
+    (unless (or (magit-anything-staged-p)
+                allow-empty
+                amend
+                tag-name
+                (file-exists-p (concat (magit-git-dir) "MERGE_HEAD"))
+                (and commit-all
+                     (not (magit-everything-clean-p))))
+      (error "Refusing to create empty commit. Maybe you want to amend (%s) or allow-empty (%s)?"
+             (key-description (car (where-is-internal
+                                    'magit-log-edit-toggle-amending)))
+             (key-description (car (where-is-internal
+                                    'magit-log-edit-toggle-allow-empty)))))
+
+    (magit-log-edit-push-to-comment-ring (buffer-string))
+    (magit-log-edit-setup-author-env author)
+    (magit-log-edit-set-fields nil)
+    (magit-log-edit-cleanup)
+    (if (= (buffer-size) 0)
+        (insert "(Empty description)\n"))
+    (let ((env process-environment)
+          (commit-buf (current-buffer)))
+      (with-current-buffer (magit-find-status-buffer default-directory)
+        (let ((process-environment env))
+          (cond (tag-name
+                 (apply #'magit-run-git-with-input commit-buf
+                        "tag" (append tag-options (list tag-name "-a" "-F" "-" tag-rev))))
+                (t
+                 (apply #'magit-run-async-with-input commit-buf
+                        magit-git-executable
+                        (append magit-git-standard-options
+                                '("commit")
+                                magit-custom-options
+                                '("-F" "-")
+                                (if (and commit-all (not allow-empty)) '("--all") '())
+                                (if amend '("--amend") '())
+                                (if allow-empty '("--allow-empty"))
+                                (if sign-off '("--signoff") '()))))))))
+    ;; shouldn't we kill that buffer altogether?
+    (erase-buffer)
+    (let ((magit-buf magit-buffer-internal))
+      (bury-buffer)
+      (set-buffer magit-buf))
+    (when (file-exists-p (concat (magit-git-dir) "MERGE_MSG"))
+      (delete-file (concat (magit-git-dir) "MERGE_MSG")))
+    ;; potentially the local environment has been altered with settings that
+    ;; were specific to this commit. Let's revert it
+    (kill-local-variable 'process-environment)
+    (magit-update-vc-modeline default-directory)
+    (when magit-pre-log-edit-window-configuration
+      (set-window-configuration magit-pre-log-edit-window-configuration)
+      (setq magit-pre-log-edit-window-configuration nil))))
+
+(defun magit-log-edit-cancel-log-message ()
+  "Abort edits and erase commit message being composed."
+  (interactive)
+  (when (or (not magit-log-edit-confirm-cancellation)
+            (yes-or-no-p
+             "Really cancel editing the log (any changes will be lost)?"))
+    (erase-buffer)
+    (bury-buffer)
+    (when magit-pre-log-edit-window-configuration
+      (set-window-configuration magit-pre-log-edit-window-configuration)
+      (setq magit-pre-log-edit-window-configuration nil))))
+
+(defun magit-log-edit-toggle-amending ()
+  "Toggle whether this will be an amendment to the previous commit.
+\(i.e., whether eventual commit does 'git commit --amend')"
+  (interactive)
+  (when (eq (magit-log-edit-toggle-field 'amend t) 'first)
+    (magit-log-edit-append
+     (magit-trim-line (magit-format-commit "HEAD" "%s%n%n%b")))))
+
+(defun magit-log-edit-toggle-signoff ()
+  "Toggle whether this commit will include a signoff.
+\(i.e., whether eventual commit does 'git commit --signoff')"
+  (interactive)
+  (magit-log-edit-toggle-field 'sign-off (not magit-commit-signoff)))
+
+(defun magit-log-edit-toggle-author ()
+  "Toggle whether this commit will include an author.
+\(i.e., whether eventual commit is run with GIT_AUTHOR_NAME and
+GIT_AUTHOR_EMAIL set)"
+  (interactive)
+  (magit-log-edit-toggle-input 'author (format "%s <%s>"
+                                               (or (magit-get "user" "name") "Author Name")
+                                               (or (magit-get "user" "email") "author@email"))))
+
+(defun magit-log-edit-toggle-allow-empty ()
+  "Toggle whether this commit is allowed to be empty.
+This means that the eventual commit does 'git commit --allow-empty'."
+  (interactive)
+  (magit-log-edit-toggle-field 'allow-empty t))
+
+(defun magit-pop-to-log-edit (operation)
+  (let ((dir default-directory)
+        (magit-buf (current-buffer))
+        (buf (get-buffer-create magit-log-edit-buffer-name)))
+    (setq magit-pre-log-edit-window-configuration
+          (current-window-configuration))
+    (pop-to-buffer buf)
+    (setq default-directory dir)
+    (when (file-exists-p (concat (magit-git-dir) "MERGE_MSG"))
+      (insert-file-contents (concat (magit-git-dir) "MERGE_MSG")))
+    (magit-log-edit-mode)
+    (make-local-variable 'magit-buffer-internal)
+    (setq magit-buffer-internal magit-buf)
+    (message "Type C-c C-c to %s (C-c C-k to cancel)." operation)))
+
+(defun magit-log-edit (&optional arg)
+  "Brings up a buffer to allow editing of commit messages.
+
+Giving a simple prefix arg will amend a previous commit, while
+a double prefix arg will allow creating an empty one.
+
+If there is a rebase in progress, offer the user the option to
+continue it.
+
+\\{magit-log-edit-mode-map}"
+  (interactive "P")
+  ;; If repository is dirty there is no point in trying to
+  ;; suggest to continue the rebase. Git will rebuke you and exit with
+  ;; error code, so suggest it only if theres absolutely nothing else
+  ;; to do and rebase is ongoing.
+  (if (and (magit-everything-clean-p)
+           (magit-rebase-info)
+           (y-or-n-p "Rebase in progress.  Continue it? "))
+      (magit-run-git-async "rebase" "--continue")
+
+    ;; If there's nothing staged, set commit flag to `nil', thus
+    ;; avoiding unnescessary popping up of the log edit buffer in case
+    ;; when user chose to forgo commiting all unstaged changes
+    (let ((amend-p (= (prefix-numeric-value arg) 4))
+          (empty-p (= (prefix-numeric-value arg) 16)))
+      (when (and magit-commit-all-when-nothing-staged
+                 (not (magit-everything-clean-p))
+                 (not (magit-anything-staged-p)))
+        (cond ((eq magit-commit-all-when-nothing-staged 'ask-stage)
+               (when (y-or-n-p "Nothing staged.  Stage everything now? ")
+                 (magit-stage-all)))
+              ((not (magit-log-edit-get-field 'commit-all))
+               (when (or (eq magit-commit-all-when-nothing-staged t)
+                         (y-or-n-p
+                          "Nothing staged.  Commit all unstaged changes? "))
+                 (magit-log-edit-set-field 'commit-all "yes")))))
+      (when amend-p
+        (magit-log-edit-toggle-amending))
+      (when empty-p
+        (magit-log-edit-toggle-allow-empty))
+      (let ((author-email (or (getenv "GIT_AUTHOR_EMAIL") ""))
+            (author-name (or (getenv "GIT_AUTHOR_NAME") ""))
+            (author-date (or (getenv "GIT_AUTHOR_DATE") "")))
+        (if (not (string= author-email ""))
+            (magit-log-edit-set-field 'author (format "%s <%s>%s"
+                                                      (if (string= "" author-name) author-email author-name)
+                                                      author-email
+                                                      (if (string= "" author-date) "" (format ", %s" author-date))))))
+      (magit-pop-to-log-edit "commit"))))
+
+(defun magit-add-log ()
+  (interactive)
+  (cond ((magit-rebase-info)
+         (if (y-or-n-p "Rebase in progress.  Continue it? ")
+             (magit-run-git-async "rebase" "--continue")))
+        (t
+         (let ((section (magit-current-section)))
+           (let ((fun (if (eq (magit-section-type section) 'hunk)
+                          (save-window-excursion
+                            (save-excursion
+                              (magit-visit-item)
+                              (add-log-current-defun)))
+                        nil))
+                 (file (magit-diff-item-file
+                        (cond ((eq (magit-section-type section) 'hunk)
+                               (magit-hunk-item-diff section))
+                              ((eq (magit-section-type section) 'diff)
+                               section)
+                              (t
+                               (error "No change at point"))))))
+             (magit-log-edit nil)
+             (goto-char (point-min))
+             (cond ((not (search-forward-regexp
+                          (format "^\\* %s" (regexp-quote file)) nil t))
+                    ;; No entry for file, create it.
+                    (goto-char (point-max))
+                    (insert (format "\n* %s" file))
+                    (if fun
+                        (insert (format " (%s)" fun)))
+                    (insert ": "))
+                   (fun
+                    ;; found entry for file, look for fun
+                    (let ((limit (or (save-excursion
+                                       (and (search-forward-regexp "^\\* "
+                                                                   nil t)
+                                            (match-beginning 0)))
+                                     (point-max))))
+                      (cond ((search-forward-regexp (format "(.*\\<%s\\>.*):"
+                                                            (regexp-quote fun))
+                                                    limit t)
+                             ;; found it, goto end of current entry
+                             (if (search-forward-regexp "^(" limit t)
+                                 (backward-char 2)
+                               (goto-char limit)))
+                            (t
+                             ;; not found, insert new entry
+                             (goto-char limit)
+                             (if (bolp)
+                                 (open-line 1)
+                               (newline))
+                             (insert (format "(%s): " fun))))))
+                   (t
+                    ;; found entry for file, look for beginning  it
+                    (when (looking-at ":")
+                      (forward-char 2)))))))))
+
+;;; Tags
+
+(magit-define-command tag (name rev)
+  "Create a new lightweight tag with the given NAME at REV.
+\('git tag NAME')."
+  (interactive
+   (list
+    (read-string "Tag name: ")
+    (magit-read-rev "Place tag on: " (or (magit-default-rev) "HEAD"))))
+  (apply #'magit-run-git "tag" (append magit-custom-options (list name rev))))
+
+(magit-define-command annotated-tag (name rev)
+  "Start composing an annotated tag with the given NAME.
+Tag will point to the current 'HEAD'."
+  (interactive
+   (list
+    (read-string "Tag name: ")
+    (magit-read-rev "Place tag on: " (or (magit-default-rev) "HEAD"))))
+  (magit-log-edit-set-field 'tag-name name)
+  (magit-log-edit-set-field 'tag-rev rev)
+  (magit-log-edit-set-field 'tag-options magit-custom-options)
+  (magit-pop-to-log-edit "tag"))
+
+;;; Stashing
+
+(defun magit-wash-stash ()
+  (if (search-forward-regexp "stash@{\\(.*?\\)}" (line-end-position) t)
+      (let ((stash (match-string-no-properties 0))
+            (name (match-string-no-properties 1)))
+        (delete-region (match-beginning 0) (match-end 0))
+        (goto-char (match-beginning 0))
+        (fixup-whitespace)
+        (goto-char (line-beginning-position))
+        (insert name)
+        (goto-char (line-beginning-position))
+        (magit-with-section stash 'stash
+          (magit-set-section-info stash)
+          (forward-line)))
+    (forward-line))
+  t)
+
+(defun magit-wash-stashes ()
+  (let ((magit-old-top-section nil))
+    (magit-wash-sequence #'magit-wash-stash)))
+
+(magit-define-inserter stashes ()
+  (magit-git-section 'stashes
+                     "Stashes:" 'magit-wash-stashes
+                     "stash" "list"))
+
+(magit-define-command stash (description)
+  "Create new stash of working tree and staging area named DESCRIPTION.
+Working tree and staging area revert to the current 'HEAD'.
+With prefix argument, changes in staging area are kept.
+\('git stash save [--keep-index] DESCRIPTION')"
+  (interactive "sStash description: ")
+  (apply 'magit-run-git `("stash" "save" ,@magit-custom-options "--" ,description)))
+
+(magit-define-command stash-snapshot ()
+  "Create new stash of working tree and staging area; keep changes in place.
+\('git stash save \"Snapshot...\"; git stash apply stash@{0}')"
+  (interactive)
+  (magit-with-refresh
+    (apply 'magit-run-git `("stash" "save" ,@magit-custom-options
+                   ,(format-time-string "Snapshot taken at %Y-%m-%d %H:%M:%S"
+                                       (current-time))))
+    (magit-run-git "stash" "apply" "stash@{0}")))
+
+(defvar magit-currently-shown-stash nil)
+
+(define-derived-mode magit-stash-mode magit-mode "Magit Stash"
+  "Mode for looking at a git stash.
+
+\\{magit-stash-mode-map}"
+  :group 'magit)
+
+(defvar magit-stash-buffer-name "*magit-stash*"
+  "Buffer name for displaying a stash.")
+
+(defun magit-show-stash (stash &optional scroll)
+  (when (magit-section-p stash)
+    (setq stash (magit-section-info stash)))
+  (let ((dir default-directory)
+        (buf (get-buffer-create magit-stash-buffer-name))
+        (stash-id (magit-git-string "rev-list" "-1" stash)))
+    (cond ((and (equal magit-currently-shown-stash stash-id)
+                (with-current-buffer buf
+                  (> (length (buffer-string)) 1)))
+           (let ((win (get-buffer-window buf)))
+             (cond ((not win)
+                    (display-buffer buf))
+                   (scroll
+                    (with-selected-window win
+                      (funcall scroll))))))
+          (t
+           (setq magit-currently-shown-stash stash-id)
+           (display-buffer buf)
+           (with-current-buffer buf
+             (set-buffer buf)
+             (goto-char (point-min))
+             (let* ((range (cons (concat stash "^2^") stash))
+                    (magit-current-diff-range range)
+                    (args (magit-rev-range-to-git range)))
+               (magit-mode-init dir 'magit-diff-mode #'magit-refresh-diff-buffer
+                                range args)))))))
+;;; Commits
+
+(defun magit-commit-at-point (&optional nil-ok-p)
+  (let* ((section (magit-current-section))
+         (commit (if (and section
+                          (eq (magit-section-type section) 'commit))
+                     (magit-section-info section)
+                 (get-text-property (point) 'revision))))
+    (if nil-ok-p
+        commit
+      (or commit
+          (error "No commit at point")))))
+
+(defun magit-apply-commit (commit &optional docommit noerase revert)
+  (let* ((parent-id (magit-choose-parent-id commit "cherry-pick"))
+         (success (magit-run* `(,magit-git-executable
+                                ,@magit-git-standard-options
+                                ,(if revert "revert" "cherry-pick")
+                                ,@(if parent-id
+                                      (list "-m" (number-to-string parent-id)))
+                                ,@(if (not docommit) (list "--no-commit"))
+                                ,commit)
+                              nil noerase)))
+    (when (and (not docommit) success)
+      (cond (revert
+             (magit-log-edit-append
+              (magit-format-commit commit "Reverting \"%s\"")))
+            (t
+             (magit-log-edit-append
+              (magit-format-commit commit "%s%n%n%b"))
+             (magit-log-edit-set-field
+              'author
+              (magit-format-commit commit "%an <%ae>, %ai")))))
+    success))
+
+(defun magit-apply-item ()
+  (interactive)
+  (magit-section-action (item info "apply")
+    ((pending commit)
+     (magit-apply-commit info)
+     (magit-rewrite-set-commit-property info 'used t))
+    ((commit)
+     (magit-apply-commit info))
+    ((unstaged *)
+     (error "Change is already in your working tree"))
+    ((staged *)
+     (error "Change is already in your working tree"))
+    ((hunk)
+     (magit-apply-hunk-item item))
+    ((diff)
+     (magit-apply-diff-item item))
+    ((stash)
+     (magit-run-git "stash" "apply" info))))
+
+(defun magit-cherry-pick-item ()
+  (interactive)
+  (magit-section-action (item info "cherry-pick")
+    ((pending commit)
+     (magit-apply-commit info t)
+     (magit-rewrite-set-commit-property info 'used t))
+    ((commit)
+     (magit-apply-commit info t))
+    ((stash)
+     (magit-run-git "stash" "pop" info))))
+
+(defmacro magit-with-revert-confirmation (&rest body)
+  `(when (or (not magit-revert-item-confirm)
+             (yes-or-no-p "Really revert this item? "))
+     ,@body))
+
+(defun magit-revert-item ()
+  (interactive)
+  (magit-section-action (item info "revert")
+    ((pending commit)
+     (magit-with-revert-confirmation
+      (magit-apply-commit info nil nil t)
+      (magit-rewrite-set-commit-property info 'used nil)))
+    ((commit)
+     (magit-with-revert-confirmation
+      (magit-apply-commit info nil nil t)))
+    ;; Reverting unstaged changes cannot be undone
+    ((unstaged *)
+     (magit-discard-item))
+    ((hunk)
+     (magit-with-revert-confirmation
+      (magit-apply-hunk-item-reverse item)))
+    ((diff)
+     (magit-with-revert-confirmation
+      (magit-apply-diff-item item "--reverse")))))
+
+(defun magit-log-show-more-entries (&optional arg)
+  "Grow the number of log entries shown.
+
+With no prefix optional ARG, show twice as many log entries.
+With a numerical prefix ARG, add this number to the number of shown log entries.
+With a non numeric prefix ARG, show all entries"
+  (interactive "P")
+  (make-local-variable 'magit-log-cutoff-length)
+  (cond
+   ((numberp arg)
+    (setq magit-log-cutoff-length (+ magit-log-cutoff-length arg)))
+   (arg
+    (setq magit-log-cutoff-length magit-log-infinite-length))
+   (t (setq magit-log-cutoff-length (* magit-log-cutoff-length 2))))
+  (let ((old-point (point)))
+    (magit-refresh)
+    (goto-char old-point)))
+
+(defun magit-refresh-log-buffer (range style args)
+  (magit-configure-have-graph)
+  (magit-configure-have-decorate)
+  (magit-configure-have-abbrev)
+  (setq magit-current-range range)
+  (magit-create-log-buffer-sections
+    (apply #'magit-git-section nil
+           (magit-rev-range-describe range "Commits")
+           (apply-partially 'magit-wash-log style)
+           `("log"
+             ,(format "--max-count=%s" magit-log-cutoff-length)
+             ,"--abbrev-commit"
+             ,(format "--abbrev=%s" magit-sha1-abbrev-length)
+             ,@(cond ((eq style 'long) (list "--stat" "-z"))
+                     ((eq style 'oneline) (list "--pretty=oneline"))
+                     (t nil))
+             ,@(if magit-have-decorate (list "--decorate=full"))
+             ,@(if magit-have-graph (list "--graph"))
+             ,@args
+             "--"))))
+
+(define-derived-mode magit-log-mode magit-mode "Magit Log"
+  "Mode for looking at git log.
+
+\\{magit-log-mode-map}"
+  :group 'magit)
+
+(defvar magit-log-buffer-name "*magit-log*"
+  "Buffer name for display of log entries.")
+
+(magit-define-command log-ranged ()
+  (interactive)
+  (magit-log t))
+(define-obsolete-function-alias 'magit-display-log-ranged 'magit-log-ranged)
+
+(magit-define-command log (&optional ask-for-range &rest extra-args)
+  (interactive)
+  (let* ((log-range (if ask-for-range
+                        (magit-read-rev-range "Log" "HEAD")
+                      "HEAD"))
+         (topdir (magit-get-top-dir default-directory))
+         (args (nconc (list (magit-rev-range-to-git log-range))
+                      magit-custom-options
+                      extra-args)))
+    (magit-buffer-switch magit-log-buffer-name)
+    (magit-mode-init topdir 'magit-log-mode #'magit-refresh-log-buffer log-range
+                     'oneline args)))
+
+(define-obsolete-function-alias 'magit-display-log 'magit-log)
+
+(magit-define-command log-long-ranged ()
+  (interactive)
+  (magit-log-long t))
+
+(magit-define-command log-long (&optional ranged)
+  (interactive)
+  (let* ((range (if ranged
+                    (magit-read-rev-range "Long log" "HEAD")
+                  "HEAD"))
+         (topdir (magit-get-top-dir default-directory))
+         (args (append (list (magit-rev-range-to-git range))
+                       magit-custom-options)))
+    (magit-buffer-switch magit-log-buffer-name)
+    (magit-mode-init topdir 'magit-log-mode #'magit-refresh-log-buffer range
+                     'long args)))
+
+;;; Reflog
+
+(defvar magit-reflog-head nil
+  "The HEAD of the reflog in the current buffer.
+This is only non-nil in reflog buffers.")
+(make-variable-buffer-local 'magit-reflog-head)
+
+(defun magit-refresh-reflog-buffer (head args)
+  (setq magit-reflog-head head)
+  (magit-create-log-buffer-sections
+    (apply #'magit-git-section
+           'reflog (format "Local history of head %s" head) 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    "--walk-reflogs"
+                    (format "--max-count=%s" magit-log-cutoff-length)
+                    args)))))
+
+(define-derived-mode magit-reflog-mode magit-log-mode "Magit Reflog"
+  "Mode for looking at git reflog.
+
+\\{magit-reflog-mode-map}"
+  :group 'magit)
+
+(magit-define-command reflog (&optional ask-for-range)
+  (interactive)
+  (let ((at (or (if ask-for-range
+                    (magit-read-rev "Reflog of" (or (magit-guess-branch) "HEAD")))
+                "HEAD")))
+    (let* ((topdir (magit-get-top-dir default-directory))
+           (args (magit-rev-to-git at)))
+      (magit-buffer-switch "*magit-reflog*")
+      (magit-mode-init topdir 'magit-reflog-mode
+                       #'magit-refresh-reflog-buffer at args))))
+
+(magit-define-command reflog-ranged ()
+  (interactive)
+  (magit-reflog t))
+
+;;; Diffing
+
+(defvar magit-ediff-buffers nil
+  "List of buffers that may be killed by `magit-ediff-restore'.")
+
+(defvar magit-ediff-windows nil
+  "The window configuration that will be restored when Ediff is finished.")
+
+(defun magit-ediff()
+  "View the current DIFF section in ediff."
+  (interactive)
+  (let ((diff (magit-current-section)))
+    (when (magit-section-hidden diff)
+      ;; Range is not set until the first time the diff is visible.
+      ;; This somewhat hackish code makes sure it's been visible at least once.
+      (magit-toggle-section)
+      (magit-toggle-section)
+      (setq diff (magit-current-section)))
+    (if (eq 'hunk (magit-section-type diff))
+        (setq diff (magit-section-parent diff)))
+    (unless (eq 'diff (magit-section-type diff))
+      (error "No diff at this location"))
+    (let* ((type (magit-diff-item-kind diff))
+           (file1 (magit-diff-item-file diff))
+           (file2 (magit-diff-item-file2 diff))
+           (range (magit-diff-item-range diff)))
+      (cond
+       ((memq type '(new deleted typechange))
+        (message "Why ediff a %s file?" type))
+       ((and (eq type 'unmerged)
+             (eq (cdr range) 'working))
+        (magit-interactive-resolve file1))
+       ((consp (car range))
+        (magit-ediff* (magit-show (caar range) file2)
+                      (magit-show (cdar range) file2)
+                      (magit-show (cdr range) file1)))
+       (t
+        (magit-ediff* (magit-show (car range) file2)
+                      (magit-show (cdr range) file1)))))))
+
+(defun magit-ediff* (a b &optional c)
+  (setq magit-ediff-buffers (list a b c))
+  (setq magit-ediff-windows (current-window-configuration))
+  (add-hook 'ediff-quit-hook 'magit-ediff-restore 'append)
+  (if c
+      (ediff-buffers3 a b c)
+    (ediff-buffers a b)))
+
+(defun magit-ediff-restore()
+  "Kill any buffers in `magit-ediff-buffers' that are not visiting files and
+restore the window state that was saved before ediff was called."
+  (dolist (buffer magit-ediff-buffers)
+    (if (and (null (buffer-file-name buffer))
+             (buffer-live-p buffer))
+        (kill-buffer buffer)))
+  (setq magit-ediff-buffers nil)
+  (set-window-configuration magit-ediff-windows)
+  (remove-hook 'ediff-quit-hook 'magit-ediff-restore))
+
+(defun magit-refresh-diff-buffer (range args)
+  (let ((magit-current-diff-range (cond
+                                   ((stringp range)
+                                    (cons range 'working))
+                                   ((null (cdr range))
+                                    (cons (car range) 'working))
+                                   (t
+                                    range))))
+    (setq magit-current-range range)
+    (magit-create-buffer-sections
+      (magit-git-section 'diffbuf
+                         (magit-rev-range-describe range "Changes")
+                         'magit-wash-diffs
+                         "diff" (magit-diff-U-arg) args "--"))))
+
+(define-derived-mode magit-diff-mode magit-mode "Magit Diff"
+  "Mode for looking at a git diff.
+
+\\{magit-diff-mode-map}"
+  :group 'magit)
+
+(magit-define-command diff (range)
+  (interactive (list (magit-read-rev-range "Diff")))
+  (if range
+      (let* ((dir default-directory)
+             (args (magit-rev-range-to-git range))
+             (buf (get-buffer-create "*magit-diff*")))
+        (display-buffer buf)
+        (with-current-buffer buf
+          (magit-mode-init dir 'magit-diff-mode #'magit-refresh-diff-buffer range args)))))
+
+(magit-define-command diff-working-tree (rev)
+  (interactive (list (magit-read-rev "Diff with" (magit-default-rev))))
+  (magit-diff (or rev "HEAD")))
+
+(defun magit-diff-with-mark ()
+  (interactive)
+  (magit-diff (cons (magit-marked-commit)
+                    (magit-commit-at-point))))
+
+;;; Wazzup
+
+(defvar magit-wazzup-head nil
+  "The integration head for the current wazzup buffer.
+This is only non-nil in wazzup buffers.")
+(make-variable-buffer-local 'magit-wazzup-head)
+
+(defvar magit-wazzup-all-p nil
+  "Non-nil if the current wazzup buffer displays excluded branches.
+This is only meaningful in wazzup buffers.")
+(make-variable-buffer-local 'magit-wazzup-all-p)
+
+(defun magit-wazzup-toggle-ignore (branch edit)
+  (let ((ignore-file (concat (magit-git-dir) "info/wazzup-exclude")))
+    (if edit
+        (setq branch (read-string "Branch to ignore for wazzup: " branch)))
+    (let ((ignored (magit-file-lines ignore-file)))
+      (cond ((member branch ignored)
+             (when (or (not edit)
+                       (y-or-n-p "Branch %s is already ignored.  Unignore? "))
+               (setq ignored (delete branch ignored))))
+            (t
+             (setq ignored (append ignored (list branch)))))
+      (magit-write-file-lines ignore-file ignored)
+      (magit-need-refresh))))
+
+(defun magit-refresh-wazzup-buffer (head all)
+  (setq magit-wazzup-head head)
+  (setq magit-wazzup-all-p all)
+  (let ((branch-desc (or head "(detached) HEAD")))
+    (unless head (setq head "HEAD"))
+    (magit-create-buffer-sections
+      (magit-with-section 'wazzupbuf nil
+        (insert (format "Wazzup, %s\n\n" branch-desc))
+        (let* ((excluded (magit-file-lines (concat (magit-git-dir) "info/wazzup-exclude")))
+               (all-branches (magit-list-interesting-refs))
+               (branches (if all all-branches
+                           (delq nil (mapcar
+                                      (lambda (b)
+                                        (and (not
+                                              (member (cdr b) excluded))
+                                             b))
+                                      all-branches))))
+               (reported (make-hash-table :test #'equal)))
+          (dolist (branch branches)
+            (let* ((name (car branch))
+                   (ref (cdr branch))
+                   (hash (magit-rev-parse ref))
+                   (reported-branch (gethash hash reported)))
+              (unless (or (and reported-branch
+                               (string= (file-name-nondirectory ref)
+                                        reported-branch))
+                          (not (magit-git-string "merge-base" head ref)))
+                (puthash hash (file-name-nondirectory ref) reported)
+                (let* ((n (length (magit-git-lines "log" "--pretty=oneline"
+                                                   (concat head ".." ref))))
+                       (section
+                        (let ((magit-section-hidden-default t))
+                          (magit-git-section
+                           (cons ref 'wazzup)
+                           (format "%s unmerged commits in %s%s"
+                                   n name
+                                   (if (member ref excluded)
+                                       " (normally ignored)"
+                                     ""))
+                           'magit-wash-log
+                           "log"
+                           (format "--max-count=%s" magit-log-cutoff-length)
+                           "--abbrev-commit"
+                           (format "--abbrev=%s" magit-sha1-abbrev-length)
+                           "--graph"
+                           "--pretty=oneline"
+                           (format "%s..%s" head ref)
+                           "--"))))
+                  (magit-set-section-info ref section))))))))))
+
+(define-derived-mode magit-wazzup-mode magit-mode "Magit Wazzup"
+  "Mode for looking at commits that could be merged from other branches.
+
+\\{magit-wazzup-mode-map}"
+  :group 'magit)
+
+(defun magit-wazzup (&optional all)
+  (interactive "P")
+  (let ((topdir (magit-get-top-dir default-directory))
+        (current-branch (magit-get-current-branch)))
+    (magit-buffer-switch "*magit-wazzup*")
+    (magit-mode-init topdir 'magit-wazzup-mode
+                     #'magit-refresh-wazzup-buffer
+                     current-branch all)))
+
+(defun magit-filename (filename)
+  "Return the path of FILENAME relative to its git repository.
+
+If FILENAME is absolute, return a path relative to the git
+repository containing it. Otherwise, return a path relative to
+the current git repository."
+  (let ((topdir (expand-file-name
+                 (magit-get-top-dir (or (file-name-directory filename)
+                                        default-directory))))
+        (file (file-truename filename)))
+    (when (and (not (string= topdir ""))
+               ;; FILE must start with the git repository path
+               (zerop (string-match-p (concat "\\`" topdir) file)))
+      (substring file (length topdir)))))
+
+;; This variable is used to keep track of the current file in the
+;; *magit-log* buffer when this one is dedicated to showing the log of
+;; just 1 file.
+(defvar magit-file-log-file nil)
+(make-variable-buffer-local 'magit-file-log-file)
+
+(defun magit-refresh-file-log-buffer (file range style)
+  "Refresh the current file-log buffer by calling git.
+
+FILE is the path of the file whose log must be displayed.
+
+`magit-current-range' will be set to the value of RANGE.
+
+STYLE controls the display. It is either `'long',  `'oneline', or something else.
+ "
+  (magit-configure-have-graph)
+  (magit-configure-have-decorate)
+  (magit-configure-have-abbrev)
+  (setq magit-current-range range)
+  (setq magit-file-log-file file)
+  (magit-create-log-buffer-sections
+    (apply #'magit-git-section nil
+           (magit-rev-range-describe range (format "Commits for file %s" file))
+           (apply-partially 'magit-wash-log style)
+           `("log"
+             ,(format "--max-count=%s" magit-log-cutoff-length)
+             ,"--abbrev-commit"
+             ,(format "--abbrev=%s" magit-sha1-abbrev-length)
+             ,@(cond ((eq style 'long) (list "--stat" "-z"))
+                     ((eq style 'oneline) (list "--pretty=oneline"))
+                     (t nil))
+             ,@(if magit-have-decorate (list "--decorate=full"))
+             ,@(if magit-have-graph (list "--graph"))
+             "--"
+             ,file))))
+
+(defun magit-file-log (&optional all)
+  "Display the log for the currently visited file or another one.
+
+With a prefix argument or if no file is currently visited, ask
+for the file whose log must be displayed."
+  (interactive "P")
+  (let ((topdir (magit-get-top-dir default-directory))
+        (current-file (magit-filename
+                       (if (or current-prefix-arg (not buffer-file-name))
+                           (magit-read-file-from-rev (magit-get-current-branch))
+                        buffer-file-name)))
+        (range "HEAD"))
+    (magit-buffer-switch "*magit-log*")
+    (magit-mode-init topdir 'magit-log-mode
+                     #'magit-refresh-file-log-buffer
+                     current-file range 'oneline)))
+
+(defun magit-show-file-revision ()
+  "Open a new buffer showing the current file in the revision at point."
+  (interactive)
+  (flet ((magit-show-file-from-diff (item)
+                                    (switch-to-buffer-other-window
+                                     (magit-show (cdr (magit-diff-item-range item))
+                                                 (magit-diff-item-file item)))))
+    (magit-section-action (item info "show")
+      ((commit)
+       (let ((current-file (or magit-file-log-file
+                               (magit-read-file-from-rev info))))
+         (switch-to-buffer-other-window
+          (magit-show info current-file))))
+      ((hunk) (magit-show-file-from-diff (magit-hunk-item-diff item)))
+      ((diff) (magit-show-file-from-diff item)))))
+
+;;; Miscellaneous
+
+(defun magit-ignore-modifiable-file (file edit)
+  "Prompt the user for the filename to be added to git ignore.
+\\<minibuffer-local-map>
+The minibuffer's future history (accessible with \\[next-history-element])
+contains predefined values (such as wildcards) that might
+be of interest.
+The history and default value are derived from the filename FILE.
+If EDIT argument is negative, the prompt proposes wildcard by default.
+"
+  (let* ((just-extension (concat "*." (file-name-extension file)))
+         (full-extension (concat (file-name-directory file) just-extension))
+         (just-file (file-name-nondirectory file))
+         ;; change the order in history depending on the negativity of
+         ;; EDIT.
+         (history (if (< (prefix-numeric-value edit) 0)
+                      (list full-extension just-extension file just-file)
+                    (list file full-extension just-extension just-file))))
+    (read-string
+     (format "File to ignore [%s]: " (car history))
+     nil nil history)))
+
+(defun magit-ignore-file (file edit local)
+  "Add FILE to the list of files to ignore.
+\\<minibuffer-local-map>
+If EDIT is non-`nil', prompt the user for the filename to
+be added to git ignore. In this case, the minibuffer's
+future history (accessible with \\[next-history-element]) contains predefined
+values (such as wildcards) that might be of interest.
+
+If LOCAL is nil, the `.gitignore' file is updated.
+Otherwise, it is `.git/info/exclude'."
+  (let* ((local-ignore-dir (concat (magit-git-dir) "info/"))
+         (ignore-file (if local
+                          (concat local-ignore-dir "exclude")
+                        ".gitignore")))
+    (if edit
+      (setq file (magit-ignore-modifiable-file file edit)))
+    (if (and local (not (file-exists-p local-ignore-dir)))
+        (make-directory local-ignore-dir t))
+    (with-temp-buffer
+      (when (file-exists-p ignore-file)
+        (insert-file-contents ignore-file))
+      (goto-char (point-max))
+      (unless (bolp)
+        (insert "\n"))
+      (insert file "\n")
+      (write-region nil nil ignore-file))
+    (magit-need-refresh)))
+
+(defun magit-ignore-item ()
+  "Add FILE to the `.gitignore' list of files to ignore.
+\\<minibuffer-local-map>
+With a prefix argument, prompt the user for the filename to
+be added. In this case, the minibuffer's future history
+\(accessible with \\[next-history-element]) contains predefined values (such as
+wildcards) that might be of interest. If prefix argument is
+negative, the prompt proposes wildcard by default."
+  (interactive)
+  (magit-section-action (item info "ignore")
+    ((untracked file)
+     (magit-ignore-file (concat "/" info) current-prefix-arg nil))
+    ((wazzup)
+     (magit-wazzup-toggle-ignore info current-prefix-arg))))
+
+(defun magit-ignore-item-locally ()
+  "Add FILE to the `.git/info/exclude' list of files to ignore.
+\\<minibuffer-local-map>
+With a prefix argument, prompt the user for the filename to
+be added. In this case, the minibuffer's future history
+(accessible with \\[next-history-element]) contains predefined values (such as
+wildcards) that might be of interest. If prefix argument is
+negative, the prompt proposes wildcard by default."
+  (interactive)
+  (magit-section-action (item info "ignore")
+    ((untracked file)
+     (magit-ignore-file (concat "/" info) current-prefix-arg t))))
+
+(defun magit-discard-diff (diff stagedp)
+  (let ((kind (magit-diff-item-kind diff))
+        (file (magit-diff-item-file diff)))
+    (cond ((eq kind 'deleted)
+           (when (yes-or-no-p (format "Resurrect %s? " file))
+             (magit-run-git "reset" "-q" "--" file)
+             (magit-run-git "checkout" "--" file)))
+          ((eq kind 'new)
+           (if (yes-or-no-p (format "Delete %s? " file))
+               (magit-run-git "rm" "-f" "--" file)))
+          (t
+           (if (yes-or-no-p (format "Discard changes to %s? " file))
+               (if stagedp
+                   (magit-run-git "checkout" "HEAD" "--" file)
+                 (magit-run-git "checkout" "--" file)))))))
+
+(defun magit-discard-item ()
+  (interactive)
+  (magit-section-action (item info "discard")
+    ((untracked file)
+     (when (yes-or-no-p (format "Delete %s? " info))
+       (if (and (file-directory-p info)
+                (not (file-symlink-p info)))
+           (magit-delete-directory info 'recursive)
+         (delete-file info))
+       (magit-refresh-buffer)))
+    ((untracked)
+     (if (yes-or-no-p "Delete all untracked files and directories? ")
+         (magit-run-git "clean" "-df")))
+    ((unstaged diff hunk)
+     (when (yes-or-no-p (if (magit-use-region-p)
+                            "Discard changes in region? "
+                          "Discard hunk? "))
+       (magit-apply-hunk-item-reverse item)))
+    ((staged diff hunk)
+     (if (magit-file-uptodate-p (magit-diff-item-file
+                                 (magit-hunk-item-diff item)))
+         (when (yes-or-no-p (if (magit-use-region-p)
+                                "Discard changes in region? "
+                              "Discard hunk? "))
+           (magit-apply-hunk-item-reverse item "--index"))
+       (error "Can't discard this hunk.  Please unstage it first")))
+    ((unstaged diff)
+     (magit-discard-diff item nil))
+    ((staged diff)
+     (if (magit-file-uptodate-p (magit-diff-item-file item))
+         (magit-discard-diff item t)
+       (error "Can't discard staged changes to this file.  Please unstage it first")))
+    ((diff diff)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-discard-item)))
+    ((diff diff hunk)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-goto-parent-section)
+       (magit-discard-item)))
+    ((hunk)
+     (error "Can't discard this hunk"))
+    ((diff)
+     (error "Can't discard this diff"))
+    ((stash)
+     (when (yes-or-no-p "Discard stash? ")
+       (magit-run-git "stash" "drop" info)))
+    ((branch)
+     (when (yes-or-no-p (if current-prefix-arg
+                            "Force delete branch?"
+                          "Delete branch? "))
+       (magit-delete-branch info current-prefix-arg)))
+    ((remote)
+     (when (yes-or-no-p "Remove remote? ")
+       (magit-remove-remote info)))))
+
+(defun magit-move-item ()
+  (interactive)
+  (magit-section-action (item info "move")
+    ((branch)
+     (call-interactively 'magit-move-branch))
+    ((remote)
+     (call-interactively 'magit-rename-remote))))
+
+(defmacro magit-visiting-file-item (&rest body)
+  `(let ((marker (save-window-excursion
+                   (magit-visit-file-item)
+                   (set-marker (make-marker) (point)))))
+     (save-excursion
+       (with-current-buffer (marker-buffer marker)
+         (goto-char marker)
+         ,@body))))
+
+(defun magit-add-change-log-entry-no-option (&optional other-window)
+  "Add a change log entry for current change.
+With a prefix argument, edit in other window.
+The name of the change log file is set by variable change-log-default-name."
+  (interactive "P")
+  (if other-window
+      (magit-visiting-file-item (add-change-log-entry-other-window))
+    (magit-visiting-file-item (add-change-log-entry))))
+
+(defun magit-add-change-log-entry-other-window ()
+  (interactive)
+  (magit-visiting-file-item (call-interactively 'add-change-log-entry-other-window)))
+
+(eval-after-load 'dired-x
+  '(defun magit-dired-jump (&optional other-window)
+    "Visit current item.
+With a prefix argument, visit in other window."
+    (interactive "P")
+    (require 'dired-x)
+    (magit-section-action (item info "dired-jump")
+      ((untracked file)
+       (dired-jump other-window (file-truename info)))
+      ((diff)
+       (dired-jump other-window (file-truename (magit-diff-item-file item))))
+      ((hunk)
+       (dired-jump other-window
+                   (file-truename (magit-diff-item-file
+                                   (magit-hunk-item-diff item))))))))
+
+(defun magit-visit-file-item (&optional other-window)
+  "Visit current file associated with item.
+With a prefix argument, visit in other window."
+  (interactive "P")
+  (magit-section-action (item info "visit-file")
+    ((untracked file)
+     (funcall
+      (if other-window 'find-file-other-window 'find-file)
+      info))
+    ((diff)
+     (let ((file (magit-diff-item-file item)))
+       (cond ((not (file-exists-p file))
+              (error "Can't visit deleted file: %s" file))
+             ((file-directory-p file)
+              (magit-status file))
+             (t
+              (funcall
+               (if other-window 'find-file-other-window 'find-file)
+               file)))))
+    ((hunk)
+     (let ((file (magit-diff-item-file (magit-hunk-item-diff item)))
+           (line (magit-hunk-item-target-line item)))
+       (if (not (file-exists-p file))
+           (error "Can't visit deleted file: %s" file))
+       (funcall
+        (if other-window 'find-file-other-window 'find-file)
+        file)
+       (goto-char (point-min))
+       (forward-line (1- line))))))
+
+(defun magit-visit-item (&optional other-window)
+  "Visit current item.
+With a prefix argument, visit in other window."
+  (interactive "P")
+  (magit-section-action (item info "visit")
+    ((untracked file)
+     (call-interactively 'magit-visit-file-item))
+    ((diff)
+     (call-interactively 'magit-visit-file-item))
+    ((hunk)
+     (call-interactively 'magit-visit-file-item))
+    ((commit)
+     (magit-show-commit info nil nil 'select))
+    ((stash)
+     (magit-show-stash info)
+     (pop-to-buffer magit-stash-buffer-name))
+    ((branch)
+     (magit-checkout info))
+    ((longer)
+     (magit-log-show-more-entries ()))))
+
+(defun magit-show-item-or-scroll-up ()
+  (interactive)
+  (magit-section-action (item info)
+    ((commit)
+     (magit-show-commit info #'scroll-up))
+    ((stash)
+     (magit-show-stash info #'scroll-up))
+    (t
+     (scroll-up))))
+
+(defun magit-show-item-or-scroll-down ()
+  (interactive)
+  (magit-section-action (item info)
+    ((commit)
+     (magit-show-commit info #'scroll-down))
+    ((stash)
+     (magit-show-stash info #'scroll-down))
+    (t
+     (scroll-down))))
+
+(defun magit-mark-item (&optional unmark)
+  (interactive "P")
+  (if unmark
+      (magit-set-marked-commit nil)
+    (magit-section-action (item info "mark")
+      ((commit)
+       (magit-set-marked-commit (if (eq magit-marked-commit info)
+                                    nil
+                                  info))))))
+
+(defun magit-describe-item ()
+  (interactive)
+  (let ((section (magit-current-section)))
+    (message "Section: %s %s-%s %S %S %S"
+             (magit-section-type section)
+             (magit-section-beginning section)
+             (magit-section-end section)
+             (magit-section-title section)
+             (magit-section-info section)
+             (magit-section-context-type section))))
+
+(defun magit-copy-item-as-kill ()
+  "Copy sha1 of commit at point into kill ring."
+  (interactive)
+  (magit-section-action (item info "copy")
+    ((commit)
+     (kill-new info)
+     (message "%s" info))))
+
+(eval-when-compile (require 'server))
+
+(defun magit-server-running-p ()
+  "Test whether server is running (works with < 23 as well).
+
+Return values:
+  nil              the server is definitely not running.
+  t                the server seems to be running.
+  something else   we cannot determine whether it's running without using
+                   commands which may have to wait for a long time."
+  (require 'server)
+  (if (functionp 'server-running-p)
+      (server-running-p)
+    (condition-case nil
+        (if server-use-tcp
+            (with-temp-buffer
+              (insert-file-contents-literally (expand-file-name server-name server-auth-dir))
+              (or (and (looking-at "127\\.0\\.0\\.1:[0-9]+ \\([0-9]+\\)")
+                       (assq 'comm
+                             (process-attributes
+                              (string-to-number (match-string 1))))
+                       t)
+                  :other))
+          (delete-process
+           (make-network-process
+            :name "server-client-test" :family 'local :server nil :noquery t
+            :service (expand-file-name server-name server-socket-dir)))
+          t)
+      (file-error nil))))
+
+(defun magit-interactive-rebase ()
+  "Start a git rebase -i session, old school-style."
+  (interactive)
+  (unless (magit-server-running-p)
+    (server-start))
+  (let* ((section (get-text-property (point) 'magit-section))
+         (commit (and (member 'commit (magit-section-context-type section))
+                      (magit-section-info section)))
+         (old-editor (getenv "GIT_EDITOR")))
+    (setenv "GIT_EDITOR" (concat (locate-file "emacsclient" exec-path)
+                                 " -s " server-name))
+    (unwind-protect
+        (magit-run-git-async "rebase" "-i"
+                             (or (and commit (concat commit "^"))
+                                 (magit-read-rev "Interactively rebase to" (magit-guess-branch))))
+      (if old-editor
+          (setenv "GIT_EDITOR" old-editor)))))
+
+(define-derived-mode magit-branch-manager-mode magit-mode "Magit Branch"
+  "Magit Branches")
+
+(defun magit-quit-window (&optional kill-buffer)
+  "Bury the buffer and delete its window.  With a prefix argument, kill the
+buffer instead."
+  (interactive "P")
+  (quit-window kill-buffer (selected-window)))
+
+(defun magit--branch-name-at-point ()
+  "Get the branch name in the line at point."
+  (let ((branch (magit-section-info (magit-current-section))))
+    (or branch (error "No branch at point"))))
+
+(defun magit--branches-for-remote-repo (remote)
+  "Return a list of remote branch names for REMOTE.
+These are the branch names with the remote name stripped."
+  (remq nil
+        (mapcar (lambda (line)
+                  (save-match-data
+                    (if (and (not (string-match-p " -> " line))
+                             (string-match (concat "^ +" remote "/\\([^ $]+\\)")
+                                           line))
+                        (match-string 1 line))))
+                (magit-git-lines "branch" "-r"))))
+
+(defvar magit-branches-buffer-name "*magit-branches*")
+
+(defun magit--is-branch-at-point-remote ()
+  "Return non-nil if the branch at point is a remote tracking branch"
+  (magit-remote-part-of-branch (magit--branch-name-at-point)))
+
+(defun magit-remote-part-of-branch (branch)
+  (when (string-match-p "^\\(?:refs/\\)?remotes\\/" branch)
+    (loop for remote in (magit-git-lines "remote")
+          when (string-match-p (format "^\\(?:refs/\\)?remotes\\/%s\\/" (regexp-quote remote)) branch) return remote)))
+
+(defun magit-branch-no-remote (branch)
+  (let ((remote (magit-remote-part-of-branch branch)))
+    (if remote
+        (progn
+          ;; This has to match if remote is non-nil
+          (assert (string-match (format "^\\(?:refs/\\)?remotes\\/%s\\/\\(.*\\)" (regexp-quote remote)) branch)
+                  'show-args "Unexpected string-match failure: %s %s")
+          (match-string 1 branch))
+      branch)))
+
+(defun magit-wash-branch-line (&optional remote-name)
+  (looking-at (concat
+               "^\\([ *] \\)"                 ; 1: current branch marker
+               "\\(.+?\\) +"                  ; 2: branch name
+
+               "\\(?:"
+
+               "\\([0-9a-fA-F]+\\)"           ; 3: sha1
+               " "
+               "\\(?:\\["
+               "\\([^:\n]+?\\)"               ; 4: tracking (non-greedy + to avoid matching \n)
+               "\\(?:: \\)?"
+               "\\(?:ahead \\([0-9]+\\)\\)?"  ; 5: ahead
+               "\\(?:, \\)?"
+               "\\(?:behind \\([0-9]+\\)\\)?" ; 6: behind
+               "\\] \\)?"
+               "\\(?:.*\\)"                   ; message
+
+               "\\|"                          ; or
+
+               "-> "                          ; the pointer to
+               "\\(.+\\)"                     ; 7: a ref
+
+               "\\)\n"))
+
+  (let* ((current-string (match-string 1))
+         (branch         (match-string 2))
+         (sha1           (match-string 3))
+         (tracking       (match-string 4))
+         (ahead          (match-string 5))
+         (behind         (match-string 6))
+         (other-ref      (match-string 7))
+         (current (string-match-p "^\\*" current-string)))
+
+    ; the current line is deleted before being reconstructed
+    (delete-region (point)
+                   (line-beginning-position 2))
+
+    (magit-with-section branch 'branch
+      (magit-set-section-info branch)
+      (insert-before-markers
+       ; sha1
+       (propertize (or sha1
+                       (make-string magit-sha1-abbrev-length ? ))
+                   'face 'magit-log-sha1)
+       " "
+       ; current marker
+       (if current
+           "# "
+         "  ")
+       ; branch name
+       (apply 'propertize (magit-branch-no-remote branch)
+              (if current
+                  '(face magit-branch)))
+       ; other ref that this branch is pointing to
+       (if other-ref
+           (concat " -> " (substring other-ref (+ 1 (length remote-name))))
+         "")
+       ; tracking information
+       (if (and tracking
+                (equal (magit-remote-branch-for branch t)
+                       (concat "refs/remotes/" tracking)))
+           (concat " ["
+                   ; getting rid of the tracking branch name if it is the same as the branch name
+                   (let* ((tracking-remote (magit-get "branch" branch "remote"))
+                          (tracking-branch (substring tracking (+ 1 (length tracking-remote)))))
+                     (propertize (if (string= branch tracking-branch)
+                                     (concat "@ " tracking-remote)
+                                   (concat tracking-branch " @ " tracking-remote))
+                                 'face 'magit-log-head-label-remote))
+                   ; ahead/behind information
+                   (if (or ahead
+                           behind)
+                       ": "
+                     "")
+                   (if ahead
+                       (concat "ahead "
+                               (propertize ahead
+                                           'face (if current
+                                                     'magit-branch))
+                               (if behind
+                                   ", "
+                                 ""))
+                     "")
+                   (if behind
+                       (concat "behind "
+                               (propertize behind
+                                           'face 'magit-log-head-label-remote))
+                     "")
+                   "]")
+         "")
+       "\n"))))
+
+(defun magit-wash-remote-branches-group (group)
+  (let* ((remote-name (first group))
+         (url (magit-get "remote" remote-name "url"))
+         (push-url (magit-get "remote" remote-name "pushurl"))
+         (urls (concat url (if push-url
+                               (concat ", "push-url)
+                             "")))
+         (marker (second group)))
+
+    (magit-with-section (concat "remote:" remote-name) 'remote
+      (magit-set-section-info remote-name)
+      (insert-before-markers (propertize (format "%s (%s):" remote-name urls) 'face 'magit-section-title) "\n")
+      (magit-wash-branches-between-point-and-marker marker remote-name))
+    (insert-before-markers "\n")))
+
+(defun magit-wash-branches-between-point-and-marker (marker &optional remote-name)
+  (save-restriction
+    (narrow-to-region (point) marker)
+    (magit-wash-sequence
+     (if remote-name
+         (apply-partially 'magit-wash-branch-line remote-name)
+       #'magit-wash-branch-line))))
+
+(defun magit-wash-branches ()
+         ; get the names of the remotes
+  (let* ((remotes (magit-git-lines "remote"))
+         ; get the location of remotes in the buffer
+         (markers
+          (append (mapcar (lambda (remote)
+                            (save-excursion
+                              (when (search-forward-regexp
+                                     (concat "^  remotes\\/" remote) nil t)
+                                (beginning-of-line)
+                                (point-marker))))
+                          remotes)
+                  (list (save-excursion
+                          (goto-char (point-max))
+                          (point-marker)))))
+         ; list of remote elements to display in the buffer
+         (remote-groups (loop for remote in remotes
+                              for end-markers on (cdr markers)
+                              for marker = (loop for x in end-markers thereis x)
+                              collect (list remote marker))))
+
+    ; actual displaying of information
+    (magit-with-section "local" nil
+      (insert-before-markers (propertize "Local:" 'face 'magit-section-title) "\n")
+      (magit-set-section-info ".")
+      (magit-wash-branches-between-point-and-marker
+       (loop for x in markers thereis x)))
+
+    (insert-before-markers "\n")
+
+    (mapc 'magit-wash-remote-branches-group remote-groups)
+
+    ; make sure markers point to nil so that they can be garbage collected
+    (mapc (lambda (marker)
+            (when marker
+             (set-marker marker nil)))
+          markers)))
+
+(defun magit-refresh-branch-manager ()
+  (magit-create-buffer-sections
+    (magit-git-section "branches" nil 'magit-wash-branches
+                       "branch"
+                       "-vva"
+                       (format "--abbrev=%s" magit-sha1-abbrev-length))))
+
+(magit-define-command branch-manager ()
+  (interactive)
+  (let ((topdir (magit-get-top-dir default-directory)))
+    (magit-buffer-switch magit-branches-buffer-name)
+    (magit-mode-init topdir 'magit-branch-manager-mode #'magit-refresh-branch-manager)))
+
+(defun magit-change-what-branch-tracks ()
+  "Change which remote branch the current branch tracks."
+  (interactive)
+  (if (magit--is-branch-at-point-remote)
+      (error "Cannot modify a remote branch"))
+  (let* ((local-branch (magit--branch-name-at-point))
+         (new-tracked (magit-read-rev  "Change tracked branch to"
+                                       nil
+                                       (lambda (ref)
+                                         (not (string-match-p "refs/remotes/"
+                                                              ref)))))
+         new-remote new-branch)
+    (unless (string= (or new-tracked "") "")
+      (cond (;; Match refs that are unknown in the local repository if
+             ;; `magit-remote-ref-format' is set to
+             ;; `name-then-remote'. Can be useful if you want to
+             ;; create a new branch in a remote repository.
+             (string-match "^\\([^ ]+\\) +(\\(.+\\))$" ; 1: branch name; 2: remote name
+                           new-tracked)
+             (setq new-remote (match-string 2 new-tracked)
+                   new-branch (concat "refs/heads/" (match-string 1 new-tracked))))
+            ((string-match "^\\(?:refs/remotes/\\)?\\([^/]+\\)/\\(.+\\)" ; 1: remote name; 2: branch name
+                           new-tracked)
+             (setq new-remote (match-string 1 new-tracked)
+                   new-branch (concat "refs/heads/" (match-string 2 new-tracked))))
+            (t (error "Cannot parse the remote and branch name"))))
+    (magit-set new-remote "branch" local-branch "remote")
+    (magit-set new-branch "branch" local-branch "merge")
+    (magit-branch-manager)
+    (if (string= (magit-get-current-branch) local-branch)
+        (magit-refresh-buffer (magit-find-status-buffer default-directory)))))
+
+(defvar magit-ediff-file)
+
+(defun magit-interactive-resolve (file)
+  (require 'ediff)
+  (let ((merge-status (magit-git-string "ls-files" "-u" "--" file))
+        (base-buffer (generate-new-buffer (concat file ".base")))
+        (our-buffer (generate-new-buffer (concat file ".current")))
+        (their-buffer (generate-new-buffer (concat file ".merged")))
+        (windows (current-window-configuration)))
+    (if (null merge-status)
+        (error "Cannot resolve %s" file))
+    (with-current-buffer base-buffer
+      (if (string-match "^[0-9]+ [0-9a-f]+ 1" merge-status)
+          (insert (magit-git-output `("cat-file" "blob" ,(concat ":1:" file))))))
+    (with-current-buffer our-buffer
+      (if (string-match "^[0-9]+ [0-9a-f]+ 2" merge-status)
+          (insert (magit-git-output `("cat-file" "blob" ,(concat ":2:" file)))))
+      (let ((buffer-file-name file))
+        (normal-mode)))
+    (with-current-buffer their-buffer
+      (if (string-match "^[0-9]+ [0-9a-f]+ 3" merge-status)
+          (insert (magit-git-output `("cat-file" "blob" ,(concat ":3:" file)))))
+      (let ((buffer-file-name file))
+        (normal-mode)))
+    ;; We have now created the 3 buffer with ours, theirs and the ancestor files
+    (with-current-buffer (ediff-merge-buffers-with-ancestor our-buffer their-buffer base-buffer)
+      (make-local-variable 'magit-ediff-file)
+      (setq magit-ediff-file file)
+      (make-local-variable 'magit-ediff-windows)
+      (setq magit-ediff-windows windows)
+      (make-local-variable 'ediff-quit-hook)
+      (add-hook 'ediff-quit-hook
+                (lambda ()
+                  (let ((buffer-A ediff-buffer-A)
+                        (buffer-B ediff-buffer-B)
+                        (buffer-C ediff-buffer-C)
+                        (buffer-Ancestor ediff-ancestor-buffer)
+                        (file magit-ediff-file)
+                        (file-buffer)
+                        (windows magit-ediff-windows))
+                    (ediff-cleanup-mess)
+                    (find-file file)
+                    (setq file-buffer (current-buffer))
+                    (erase-buffer)
+                    (insert-buffer-substring buffer-C)
+                    (kill-buffer buffer-A)
+                    (kill-buffer buffer-B)
+                    (kill-buffer buffer-C)
+                    (when (bufferp buffer-Ancestor) (kill-buffer buffer-Ancestor))
+                    (set-window-configuration windows)
+                    (magit-save-some-buffers
+                     "Conflict resolution finished; you may save the buffer"
+                     (lambda () (eq (current-buffer) file-buffer)))))))))
+
+(defun magit-interactive-resolve-item ()
+  (interactive)
+  (magit-section-action (item info "resolv")
+    ((diff)
+     (magit-interactive-resolve (cadr info)))))
+
+(defun magit-submodule-update (&optional init)
+  "Update the submodule of the current git repository
+
+With a prefix arg, do a submodule update --init"
+  (interactive "P")
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (apply #'magit-run-git-async "submodule" "update" (if init '("--init") ()))))
+
+(defun magit-submodule-update-init ()
+  "Update and init the submodule of the current git repository."
+  (interactive)
+  (magit-submodule-update t))
+
+(defun magit-submodule-init ()
+  "Initialize the submodules"
+  (interactive)
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (magit-run-git-async "submodule" "init")))
+
+(defun magit-submodule-sync ()
+  "Synchronizes submodules' remote URL configuration"
+  (interactive)
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (magit-run-git-async "submodule" "sync")))
+
+(defun magit-run-git-gui ()
+  "Run `git gui' for the current git repository"
+  (interactive)
+  (let* ((default-directory (magit-get-top-dir default-directory)))
+    (magit-start-process "Git Gui" nil magit-git-executable "gui")))
+
+(defun magit-run-gitk ()
+  "Run `gitk --all' for the current git repository"
+  (interactive)
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (cond
+     ((eq system-type 'windows-nt)
+      ;; Gitk is a shell script, and Windows doesn't know how to
+      ;; "execute" it.  The Windows version of Git comes with an
+      ;; implementation of "sh" and everything else it needs, but
+      ;; Windows users might not have added the directory where it's
+      ;; installed to their path
+      (let ((git-bin-dir (file-name-directory magit-gitk-executable))
+            (exec-path exec-path)
+            (process-environment process-environment))
+        (when git-bin-dir
+          ;; Adding it onto the end so that anything the user
+          ;; specified will get tried first.  Emacs looks in
+          ;; exec-path; PATH is the environment variable inherited by
+          ;; the process.  I need to change both.
+          (setq exec-path (append exec-path (list git-bin-dir)))
+          (push (format "PATH=%s;%s"
+                        (getenv "PATH")
+                        (replace-regexp-in-string "/" "\\\\" git-bin-dir))
+                process-environment))
+        (magit-start-process "Gitk" nil "sh" magit-gitk-executable "--all")))
+     (t
+      (magit-start-process "Gitk" nil magit-gitk-executable "--all")))))
+
+(defun magit-load-config-extensions ()
+  "Try to load magit extensions that are defined at git config
+layer. This can be added to `magit-mode-hook' for example"
+  (dolist (ext (magit-get-all "magit.extension"))
+    (let ((sym (intern (format "magit-%s-mode" ext))))
+      (when (and (fboundp sym)
+                 (not (eq sym 'magit-wip-save-mode)))
+        (funcall sym 1)))))
+
+(provide 'magit)
+
+;; rest of magit core
+(require 'magit-key-mode)
+(require 'magit-bisect)
+
+;;; magit.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit.el-e b/.emacs.d/elpa/magit-1.2.0/magit.el-e
new file mode 100644
index 0000000..5923afc
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit.el-e
@@ -0,0 +1,6001 @@
+;;; magit.el --- control Git from Emacs
+
+;; Copyright (C) 2010 Aaron Culich.
+;; Copyright (C) 2010 Alan Falloon.
+;; Copyright (C) 2008, 2010 Alex Ott.
+;; Copyright (C) 2008, 2009, 2010 Alexey Voinov.
+;; Copyright (C) 2010 Ben Walton.
+;; Copyright (C) 2010 Chris Bernard.
+;; Copyright (C) 2010 Christian Kluge.
+;; Copyright (C) 2008 Daniel Farina.
+;; Copyright (C) 2010 David Abrahams.
+;; Copyright (C) 2009 David Wallin.
+;; Copyright (C) 2009, 2010 Hannu Koivisto.
+;; Copyright (C) 2009 Ian Eure.
+;; Copyright (C) 2009 Jesse Alama.
+;; Copyright (C) 2009 John Wiegley.
+;; Copyright (C) 2010 Leo.
+;; Copyright (C) 2008, 2009 Marcin Bachry.
+;; Copyright (C) 2008, 2009 Marius Vollmer.
+;; Copyright (C) 2010 Mark Hepburn.
+;; Copyright (C) 2010 Moritz Bunkus.
+;; Copyright (C) 2010 Nathan Weizenbaum.
+;; Copyright (C) 2010 Oscar Fuentes.
+;; Copyright (C) 2009 Pavel Holejsovsky.
+;; Copyright (C) 2011-2012 Peter J Weisberg
+;; Copyright (C) 2009, 2010 Phil Jackson.
+;; Copyright (C) 2010 Philip Weaver.
+;; Copyright (C) 2010 Ramkumar Ramachandra.
+;; Copyright (C) 2010 Remco van 't Veer.
+;; Copyright (C) 2009 René Stadler.
+;; Copyright (C) 2010 Robin Green.
+;; Copyright (C) 2010 Roger Crew.
+;; Copyright (C) 2009, 2010, 2011 Rémi Vanicat.
+;; Copyright (C) 2010 Sean Bryant.
+;; Copyright (C) 2009, 2011 Steve Purcell.
+;; Copyright (C) 2010 Timo Juhani Lindfors.
+;; Copyright (C) 2010, 2011 Yann Hodique.
+;; Copyright (C) 2010 Ævar Arnfjörð Bjarmason.
+;; Copyright (C) 2010 Óscar Fuentes.
+
+;; Original Author: Marius Vollmer <marius.vollmer@nokia.com>
+;; Former Maintainer: Phil Jackson <phil@shellarchive.co.uk>
+;; Maintenance Group: https://github.com/organizations/magit/teams/53130
+;;   Currently composed of:
+;;   - Phil Jackson
+;;   - Peter J Weisberg
+;;   - Yann Hodique
+;;   - Rémi Vanicat
+;; Version: @GIT_DEV_VERSION@
+;; Keywords: tools
+
+;;
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Invoking the magit-status function will show a buffer with the
+;; status of the current git repository and its working tree.  That
+;; buffer offers key bindings for manipulating the status in simple
+;; ways.
+;;
+;; The status buffer mainly shows the difference between the working
+;; tree and the index, and the difference between the index and the
+;; current HEAD.  You can add individual hunks from the working tree
+;; to the index, and you can commit the index.
+;;
+;; See the Magit User Manual for more information.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'log-edit)
+(require 'easymenu)
+(require 'diff-mode)
+
+;; Silences byte-compiler warnings
+(eval-and-compile
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest args))))
+
+(eval-when-compile  (require 'view))
+(declare-function view-mode 'view)
+(eval-when-compile (require 'iswitchb))
+(eval-when-compile (require 'ido))
+(eval-when-compile (require 'ediff))
+
+;; Dummy to be used by the defcustoms when first loading the file.
+(eval-when (load eval)
+  (defalias 'magit-set-variable-and-refresh 'set-default))
+
+;;; Code:
+(defgroup magit nil
+  "Controlling Git from Emacs."
+  :prefix "magit-"
+  :group 'tools)
+
+(defcustom magit-git-executable "git"
+  "The name of the Git executable."
+  :group 'magit
+  :type 'string)
+
+(defcustom magit-gitk-executable (concat (file-name-directory magit-git-executable)
+                                         "gitk")
+  "The name of the Gitk executable."
+  :group 'magit
+  :type 'string)
+
+(defcustom magit-git-standard-options '("--no-pager")
+  "Standard options when running Git."
+  :group 'magit
+  :type '(repeat string))
+
+(defcustom magit-repo-dirs nil
+  "Directories containing Git repositories.
+Magit will look into these directories for Git repositories and
+offer them as choices for `magit-status'."
+  :group 'magit
+  :type '(repeat string))
+
+(defcustom magit-repo-dirs-depth 3
+  "The maximum depth to look for Git repos.
+When looking for a Git repository below the directories in `magit-repo-dirs',
+Magit will only descend this many levels deep."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-set-upstream-on-push nil
+  "Non-nil means that `magit-push' may use --set-upstream when pushing a branch.
+This only applies if the branch does not have an upstream set yet.
+Setting this to t will ask if --set-upstream should be used.
+Setting it to 'dontask will always use --set-upstream.
+Setting it to 'refuse will refuse to push unless a remote branch has already been set.
+
+--set-upstream is supported with git > 1.7.0"
+  :group 'magit
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Refuse" refuse)
+                 (const :tag "Always" dontask)))
+
+(defcustom magit-save-some-buffers t
+  "Non-nil means that \\[magit-status] will save modified buffers before running.
+Setting this to t will ask which buffers to save, setting it to 'dontask will
+save all modified buffers without asking."
+  :group 'magit
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Save without asking" dontask)))
+
+(defcustom magit-save-some-buffers-predicate
+  'magit-save-buffers-predicate-tree-only
+  "A predicate function to decide whether to save a buffer.
+
+Used by function `magit-save-some-buffers' when the variable of
+the same name is non-nil."
+
+  :group 'magit
+  :type '(radio (function-item magit-save-buffers-predicate-tree-only)
+                (function-item magit-save-buffers-predicate-all)
+                (function :tag "Other")))
+
+(defcustom magit-default-tracking-name-function
+  'magit-default-tracking-name-remote-plus-branch
+  "Specifies the function to use to generate default tracking branch names
+when doing a \\[magit-checkout].
+
+The default is magit-default-tracking-name-remote-plus-branch,
+which generates a tracking name of the form 'REMOTE-BRANCHNAME'."
+  :group 'magit
+  :type '(radio (function-item magit-default-tracking-name-remote-plus-branch)
+                (function-item magit-default-tracking-name-branch-only)
+                (function :tag "Other")))
+
+(defcustom magit-commit-all-when-nothing-staged 'ask
+  "Determines what \\[magit-log-edit] does when nothing is staged.
+Setting this to nil will make it do nothing, setting it to t will
+arrange things so that the actual commit command will use the \"--all\" option,
+setting it to 'ask will first ask for confirmation whether to do this,
+and setting it to 'ask-stage will cause all changes to be staged,
+after a confirmation."
+  :group 'magit
+  :type '(choice (const :tag "No" nil)
+                 (const :tag "Always" t)
+                 (const :tag "Ask" ask)
+                 (const :tag "Ask to stage everything" ask-stage)))
+
+(defcustom magit-commit-signoff nil
+  "Add the \"Signed-off-by:\" line when committing."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-sha1-abbrev-length 7
+  "The number of digits to show when a sha1 is displayed in abbreviated form."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-log-cutoff-length 100
+  "The maximum number of commits to show in the log and whazzup buffers."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-log-infinite-length 99999
+  "Number of log used to show as maximum for `magit-log-cutoff-length'."
+  :group 'magit
+  :type 'integer)
+
+(defcustom magit-log-auto-more nil
+  "Insert more log entries automatically when moving past the last entry.
+
+Only considered when moving past the last entry with
+`magit-goto-*-section' commands."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-process-popup-time -1
+  "Popup the process buffer if a command takes longer than this many seconds."
+  :group 'magit
+  :type '(choice (const :tag "Never" -1)
+                 (const :tag "Immediately" 0)
+                 (integer :tag "After this many seconds")))
+
+(defcustom magit-revert-item-confirm t
+  "Require acknowledgment before reverting an item."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-log-edit-confirm-cancellation nil
+  "Require acknowledgment before canceling the log edit buffer."
+  :group 'magit
+  :type 'boolean)
+
+(defcustom magit-remote-ref-format 'branch-then-remote
+  "What format to use for autocompleting refs, in pariticular for remotes.
+
+Autocompletion is used by functions like `magit-checkout',
+`magit-interactive-rebase' and others which offer branch name
+completion.
+
+The value 'name-then-remote means remotes will be of the
+form \"name (remote)\", while the value 'remote-slash-name
+means that they'll be of the form \"remote/name\".  I.e. something that's
+listed as \"remotes/upstream/next\" by \"git branch -l -a\"
+will be \"upstream/next\"."
+  :group 'magit
+  :type '(choice (const :tag "name (remote)" branch-then-remote)
+                 (const :tag "remote/name" remote-slash-branch)))
+
+(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
+  "Connection type used for the git process.
+
+If nil, use pipes: this is usually more efficient, and works on Cygwin.
+If t, use ptys: this enables magit to prompt for passphrases when needed."
+  :group 'magit
+  :type '(choice (const :tag "pipe" nil)
+                 (const :tag "pty" t)))
+
+(defcustom magit-completing-read-function 'magit-builtin-completing-read
+  "Function to be called when requesting input from the user."
+  :group 'magit
+  :type '(radio (function-item magit-iswitchb-completing-read)
+                (function-item magit-ido-completing-read)
+                (function-item magit-builtin-completing-read)
+                (function :tag "Other")))
+
+(defcustom magit-create-branch-behaviour 'at-head
+  "Where magit will create a new branch if not supplied a branchname or ref.
+
+The value 'at-head means a new branch will be created at the tip
+of your current branch, while the value 'at-point means magit
+will try to find a valid reference at point..."
+  :group 'magit
+  :type '(choice (const :tag "at HEAD" at-head)
+                 (const :tag "at point" at-point)))
+
+(defcustom magit-status-buffer-switch-function 'pop-to-buffer
+  "Function for `magit-status' to use for switching to the status buffer.
+
+The function is given one argument, the status buffer."
+  :group 'magit
+  :type '(radio (function-item switch-to-buffer)
+                (function-item pop-to-buffer)
+                (function :tag "Other")))
+
+(defcustom magit-rewrite-inclusive t
+  "Whether magit includes the selected base commit in a rewrite operation.
+
+t means both the selected commit as well as any subsequent
+commits will be rewritten.  This is magit's default behaviour,
+equivalent to 'git rebase -i ${REV}~1'
+
+  A'---B'---C'---D'
+  ^
+
+nil means the selected commit will be literally used as 'base',
+so only subsequent commits will be rewritten.  This is consistent
+with git-rebase, equivalent to 'git rebase -i ${REV}', yet more
+cumbersome to use from the status buffer.
+
+  A---B'---C'---D'
+  ^"
+  :group 'magit
+  :type '(choice (const :tag "Always" t)
+                 (const :tag "Never" nil)
+                 (const :tag "Ask"   ask)))
+
+(defcustom magit-highlight-whitespace t
+  "Specifies where to highlight whitespace errors.
+See `magit-highlight-trailing-whitespace',
+`magit-highlight-indentation'.  The symbol t means in all diffs,
+'status means only in the status buffer, and nil means nowhere."
+  :group 'magit
+  :type '(choice (const :tag "Always" t)
+                 (const :tag "Never" nil)
+                 (const :tag "In status buffer" status))
+  :set 'magit-set-variable-and-refresh)
+
+(defcustom magit-highlight-trailing-whitespace t
+  "Highlight whitespace at the end of a line in diffs.
+Used only when `magit-highlight-whitespace' is non-nil."
+  :group 'magit
+  :type 'boolean
+  :set 'magit-set-variable-and-refresh)
+
+(defcustom magit-highlight-indentation nil
+  "Highlight the \"wrong\" indentation style.
+Used only when `magit-highlight-whitespace' is non-nil.
+
+The value is a list of cons cells.  The car is a regular
+expression, and the cdr is the value that applies to repositories
+whose directory matches the regular expression.  If more than one
+item matches, then the *last* item in the list applies.  So, the
+default value should come first in the list.
+
+If the value is `tabs', highlight indentation with tabs.  If the
+value is an integer, highlight indentation with at least that
+many spaces.  Otherwise, highlight neither."
+  :group 'magit
+  :type `(repeat (cons (string :tag "Directory regexp")
+                       (choice (const :tag "Tabs" tabs)
+                               (integer :tag "Spaces" :value ,tab-width)
+                               (const :tag "Neither" nil))))
+  :set 'magit-set-variable-and-refresh)
+
+(defcustom magit-diff-refine-hunk nil
+  "Show fine (word-granularity) differences within diff hunks.
+
+There are three possible settings:
+
+  nil means to never show fine differences
+
+  t means to only show fine differences for the currently
+  selected diff hunk
+
+  `all' means to always show fine differences for all displayed diff hunks"
+  :group 'magit
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Selected only" t)
+                 (const :tag "All" all))
+  :set 'magit-set-variable-and-refresh)
+
+(defvar magit-current-indentation nil
+  "Indentation highlight used in the current buffer.
+This is calculated from `magit-highlight-indentation'.")
+(make-variable-buffer-local 'magit-current-indentation)
+
+(defgroup magit-faces nil
+  "Customize the appearance of Magit."
+  :prefix "magit-"
+  :group 'faces
+  :group 'magit)
+
+(defface magit-header
+  '((t :inherit header-line))
+  "Face for generic header lines.
+
+Many Magit faces inherit from this one by default."
+  :group 'magit-faces)
+
+(defface magit-section-title
+  '((t :inherit magit-header))
+  "Face for section titles."
+  :group 'magit-faces)
+
+(defface magit-branch
+  '((t :inherit magit-header))
+  "Face for the current branch."
+  :group 'magit-faces)
+
+(defface magit-diff-file-header
+  '((t :inherit diff-file-header))
+  "Face for diff file header lines."
+  :group 'magit-faces)
+
+(defface magit-diff-hunk-header
+  '((t :inherit diff-hunk-header))
+  "Face for diff hunk header lines."
+  :group 'magit-faces)
+
+(defface magit-diff-add
+  '((t :inherit diff-added))
+  "Face for lines in a diff that have been added."
+  :group 'magit-faces)
+
+(defface magit-diff-none
+  '((t :inherit diff-context))
+  "Face for lines in a diff that are unchanged."
+  :group 'magit-faces)
+
+(defface magit-diff-del
+  '((t :inherit diff-removed))
+  "Face for lines in a diff that have been deleted."
+  :group 'magit-faces)
+
+(defface magit-log-graph
+  '((((class color) (background light))
+     :foreground "grey11")
+    (((class color) (background dark))
+     :foreground "grey80"))
+  "Face for the graph element of the log output."
+  :group 'magit-faces)
+
+(defface magit-log-sha1
+  '((((class color) (background light))
+     :foreground "firebrick")
+    (((class color) (background dark))
+     :foreground "tomato"))
+  "Face for the sha1 element of the log output."
+  :group 'magit-faces)
+
+(defface magit-log-message
+  '((t))
+  "Face for the message element of the log output."
+  :group 'magit-faces)
+
+(defface magit-item-highlight
+  '((t :inherit highlight))
+  "Face for highlighting the current item."
+  :group 'magit-faces)
+
+(defface magit-item-mark
+  '((t :inherit secondary-selection))
+  "Face for highlighting marked item."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-bisect-good
+  '((((class color) (background light))
+     :box t
+     :background "light green"
+     :foreground "dark olive green")
+    (((class color) (background dark))
+     :box t
+     :background "light green"
+     :foreground "dark olive green"))
+  "Face for good bisect refs."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-bisect-bad
+  '((((class color) (background light))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4")
+    (((class color) (background dark))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4"))
+  "Face for bad bisect refs."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-remote
+  '((((class color) (background light))
+     :box t
+     :background "Grey85"
+     :foreground "OliveDrab4")
+    (((class color) (background dark))
+     :box t
+     :background "Grey11"
+     :foreground "DarkSeaGreen2"))
+  "Face for remote branch head labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-tags
+  '((((class color) (background light))
+     :box t
+     :background "LemonChiffon1"
+     :foreground "goldenrod4")
+    (((class color) (background dark))
+     :box t
+     :background "LemonChiffon1"
+     :foreground "goldenrod4"))
+  "Face for tag labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-patches
+  '((((class color) (background light))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4")
+    (((class color) (background dark))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4"))
+  "Face for Stacked Git patches."
+  :group 'magit-faces)
+
+(defface magit-whitespace-warning-face
+  '((t :inherit trailing-whitespace))
+  "Face for highlighting whitespace errors in Magit diffs."
+  :group 'magit-faces)
+
+(defvar magit-custom-options '()
+  "List of custom options to pass to Git.
+Do not customize this (used in the `magit-key-mode' implementation).")
+
+(defvar magit-read-rev-history nil
+  "The history of inputs to `magit-read-rev'.")
+
+(defvar magit-buffer-internal nil
+  "Track associated *magit* buffers.
+Do not customize this (used in the `magit-log-edit-mode' implementation
+to switch back to the *magit* buffer associated with a given commit
+operation after commit).")
+
+(defvar magit-back-navigation-history nil
+  "History items that will be visited by successively going \"back\".")
+(make-variable-buffer-local 'magit-back-navigation-history)
+(put 'magit-back-navigation-history 'permanent-local t)
+
+(defvar magit-forward-navigation-history nil
+  "History items that will be visited by successively going \"forward\".")
+(make-variable-buffer-local 'magit-forward-navigation-history)
+(put 'magit-forward-navigation-history 'permanent-local t)
+
+(defvar magit-omit-untracked-dir-contents nil
+  "When non-nil magit will only list an untracked directory, not its contents.")
+
+(defvar magit-tmp-buffer-name " *magit-tmp*")
+
+(defface magit-log-head-label-local
+  '((((class color) (background light))
+     :box t
+     :background "Grey85"
+     :foreground "LightSkyBlue4")
+    (((class color) (background dark))
+     :box t
+     :background "Grey13"
+     :foreground "LightSkyBlue1"))
+  "Face for local branch head labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-default
+  '((((class color) (background light))
+     :box t
+     :background "Grey50")
+    (((class color) (background dark))
+     :box t
+     :background "Grey50"))
+  "Face for unknown ref labels shown in log buffer."
+  :group 'magit-faces)
+
+(defvar magit-mode-map
+  (let ((map (make-keymap)))
+    (suppress-keymap map t)
+    (define-key map (kbd "n") 'magit-goto-next-section)
+    (define-key map (kbd "p") 'magit-goto-previous-section)
+    (define-key map (kbd "^") 'magit-goto-parent-section)
+    (define-key map (kbd "M-n") 'magit-goto-next-sibling-section)
+    (define-key map (kbd "M-p") 'magit-goto-previous-sibling-section)
+    (define-key map (kbd "TAB") 'magit-toggle-section)
+    (define-key map (kbd "<backtab>") 'magit-expand-collapse-section)
+    (define-key map (kbd "1") 'magit-show-level-1)
+    (define-key map (kbd "2") 'magit-show-level-2)
+    (define-key map (kbd "3") 'magit-show-level-3)
+    (define-key map (kbd "4") 'magit-show-level-4)
+    (define-key map (kbd "M-1") 'magit-show-level-1-all)
+    (define-key map (kbd "M-2") 'magit-show-level-2-all)
+    (define-key map (kbd "M-3") 'magit-show-level-3-all)
+    (define-key map (kbd "M-4") 'magit-show-level-4-all)
+    (define-key map (kbd "M-h") 'magit-show-only-files)
+    (define-key map (kbd "M-H") 'magit-show-only-files-all)
+    (define-key map (kbd "M-s") 'magit-show-level-4)
+    (define-key map (kbd "M-S") 'magit-show-level-4-all)
+    (define-key map (kbd "g") 'magit-refresh)
+    (define-key map (kbd "G") 'magit-refresh-all)
+    (define-key map (kbd "?") 'magit-describe-item)
+    (define-key map (kbd "!") 'magit-key-mode-popup-running)
+    (define-key map (kbd ":") 'magit-git-command)
+    (define-key map (kbd "C-x 4 a") 'magit-add-change-log-entry-other-window)
+    (define-key map (kbd "L") 'magit-add-change-log-entry-no-option)
+    (define-key map (kbd "RET") 'magit-visit-item)
+    (define-key map (kbd "SPC") 'magit-show-item-or-scroll-up)
+    (define-key map (kbd "DEL") 'magit-show-item-or-scroll-down)
+    (define-key map (kbd "C-w") 'magit-copy-item-as-kill)
+    (define-key map (kbd "R") 'magit-rebase-step)
+    (define-key map (kbd "t") 'magit-key-mode-popup-tagging)
+    (define-key map (kbd "r") 'magit-key-mode-popup-rewriting)
+    (define-key map (kbd "P") 'magit-key-mode-popup-pushing)
+    (define-key map (kbd "f") 'magit-key-mode-popup-fetching)
+    (define-key map (kbd "b") 'magit-key-mode-popup-branching)
+    (define-key map (kbd "M") 'magit-key-mode-popup-remoting)
+    (define-key map (kbd "B") 'magit-key-mode-popup-bisecting)
+    (define-key map (kbd "F") 'magit-key-mode-popup-pulling)
+    (define-key map (kbd "l") 'magit-key-mode-popup-logging)
+    (define-key map (kbd "$") 'magit-display-process)
+    (define-key map (kbd "c") 'magit-log-edit)
+    (define-key map (kbd "E") 'magit-interactive-rebase)
+    (define-key map (kbd "e") 'magit-ediff)
+    (define-key map (kbd "w") 'magit-wazzup)
+    (define-key map (kbd "q") 'magit-quit-window)
+    (define-key map (kbd "m") 'magit-key-mode-popup-merging)
+    (define-key map (kbd "x") 'magit-reset-head)
+    (define-key map (kbd "v") 'magit-revert-item)
+    (define-key map (kbd "a") 'magit-apply-item)
+    (define-key map (kbd "A") 'magit-cherry-pick-item)
+    (define-key map (kbd "d") 'magit-diff-working-tree)
+    (define-key map (kbd "D") 'magit-diff)
+    (define-key map (kbd "-") 'magit-diff-smaller-hunks)
+    (define-key map (kbd "+") 'magit-diff-larger-hunks)
+    (define-key map (kbd "0") 'magit-diff-default-hunks)
+    (define-key map (kbd "h") 'magit-toggle-diff-refine-hunk)
+    map))
+
+(defvar magit-commit-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-b") 'magit-show-commit-backward)
+    (define-key map (kbd "C-c C-f") 'magit-show-commit-forward)
+    map))
+
+(defvar magit-status-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "s") 'magit-stage-item)
+    (define-key map (kbd "S") 'magit-stage-all)
+    (define-key map (kbd "u") 'magit-unstage-item)
+    (define-key map (kbd "U") 'magit-unstage-all)
+    (define-key map (kbd "i") 'magit-ignore-item)
+    (define-key map (kbd "I") 'magit-ignore-item-locally)
+    (define-key map (kbd ".") 'magit-mark-item)
+    (define-key map (kbd "=") 'magit-diff-with-mark)
+    (define-key map (kbd "k") 'magit-discard-item)
+    (define-key map (kbd "C") 'magit-add-log)
+    (define-key map (kbd "X") 'magit-reset-working-tree)
+    (define-key map (kbd "z") 'magit-key-mode-popup-stashing)
+    map))
+
+(eval-after-load 'dired-x
+  '(define-key magit-status-mode-map [remap dired-jump] 'magit-dired-jump))
+
+(defvar magit-log-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd ".") 'magit-mark-item)
+    (define-key map (kbd "=") 'magit-diff-with-mark)
+    (define-key map (kbd "e") 'magit-log-show-more-entries)
+    map))
+
+(defvar magit-wazzup-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd ".") 'magit-mark-item)
+    (define-key map (kbd "=") 'magit-diff-with-mark)
+    (define-key map (kbd "i") 'magit-ignore-item)
+    map))
+
+(defvar magit-branch-manager-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "c") 'magit-create-branch)
+    (define-key map (kbd "a") 'magit-add-remote)
+    (define-key map (kbd "r") 'magit-move-item)
+    (define-key map (kbd "k") 'magit-discard-item)
+    (define-key map (kbd "T") 'magit-change-what-branch-tracks)
+    map))
+
+(defvar magit-bug-report-url
+  "http://github.com/magit/magit/issues")
+
+(defconst magit-version "@GIT_DEV_VERSION@"
+  "The version of Magit that you're using.")
+
+(defun magit-bug-report (str)
+  "Asks the user to submit a bug report about the error described in STR."
+;; XXX - should propose more information to be included.
+  (message (concat
+            "Unknown error: %s\n"
+            "Please, with as much information as possible, file a bug at\n"
+            "%s\n"
+            "You are using Magit version %s.")
+           str magit-bug-report-url magit-version))
+
+(defun magit-buffer-switch (buf)
+  (if (string-match "magit" (buffer-name))
+      (switch-to-buffer buf)
+    (pop-to-buffer buf)))
+
+;;; Macros
+
+(defmacro magit-with-refresh (&rest body)
+  (declare (indent 0))
+  `(magit-refresh-wrapper (lambda () ,@body)))
+
+;;; Git features
+
+(defvar magit-have-graph 'unset)
+(defvar magit-have-decorate 'unset)
+(defvar magit-have-abbrev 'unset)
+(make-variable-buffer-local 'magit-have-graph)
+(put 'magit-have-graph 'permanent-local t)
+(make-variable-buffer-local 'magit-have-decorate)
+(put 'magit-have-decorate 'permanent-local t)
+(make-variable-buffer-local 'magit-have-abbrev)
+(put 'magit-have-abbrev 'permanent-local t)
+
+(defun magit-configure-have-graph ()
+  (if (eq magit-have-graph 'unset)
+      (let ((res (magit-git-exit-code "log" "--graph" "--max-count=0")))
+        (setq magit-have-graph (eq res 0)))))
+
+(defun magit-configure-have-decorate ()
+  (if (eq magit-have-decorate 'unset)
+      (let ((res (magit-git-exit-code "log" "--decorate=full" "--max-count=0")))
+        (setq magit-have-decorate (eq res 0)))))
+
+(defun magit-configure-have-abbrev ()
+  (if (eq magit-have-abbrev 'unset)
+      (let ((res (magit-git-exit-code "log" "--no-abbrev-commit" "--max-count=0")))
+        (setq magit-have-abbrev (eq res 0)))))
+
+;;; Compatibilities
+
+(eval-and-compile
+  (defun magit-max-args-internal (function)
+    "Returns the maximum number of arguments accepted by FUNCTION."
+    (if (symbolp function)
+        (setq function (symbol-function function)))
+    (if (subrp function)
+        (let ((max (cdr (subr-arity function))))
+          (if (eq 'many max)
+              most-positive-fixnum
+            max))
+      (if (eq 'macro (car-safe function))
+          (setq function (cdr function)))
+      (let ((arglist (if (byte-code-function-p function)
+                         (aref function 0)
+                       (second function))))
+        (if (memq '&rest arglist)
+            most-positive-fixnum
+          (length (remq '&optional arglist))))))
+
+  (if (functionp 'start-file-process)
+      (defalias 'magit-start-process 'start-file-process)
+    (defalias 'magit-start-process 'start-process))
+
+  (unless (fboundp 'string-match-p)
+    (defun string-match-p (regexp string &optional start)
+      "Same as `string-match' except this function does not
+change the match data."
+      (let ((inhibit-changing-match-data t))
+        (string-match regexp string start))))
+
+  (if (fboundp 'with-silent-modifications)
+      (defalias 'magit-with-silent-modifications 'with-silent-modifications)
+    (defmacro magit-with-silent-modifications (&rest body)
+      "Execute body without changing `buffer-modified-p'. Also, do not
+record undo information."
+      `(set-buffer-modified-p
+        (prog1 (buffer-modified-p)
+          (let ((buffer-undo-list t)
+                before-change-functions
+                after-change-functions)
+            ,@body)))))
+
+  (if (>= (magit-max-args-internal 'delete-directory) 2)
+      (defalias 'magit-delete-directory 'delete-directory)
+    (defun magit-delete-directory (directory &optional recursive)
+      "Deletes a directory named DIRECTORY.  If RECURSIVE is non-nil,
+recursively delete all of DIRECTORY's contents as well.
+
+Does not follow symlinks."
+      (if (or (file-symlink-p directory)
+              (not (file-directory-p directory)))
+          (delete-file directory)
+        (if recursive
+            ;; `directory-files-no-dot-files-regex' borrowed from Emacs 23
+            (dolist (file (directory-files directory 'full "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"))
+              (magit-delete-directory file recursive)))
+        (delete-directory directory)))))
+
+;;; Utilities
+
+(defun magit-set-variable-and-refresh (symbol value)
+  "Set SYMBOL to VALUE and call `magit-refresh-all'"
+  (set-default symbol value)
+  (magit-refresh-all))
+
+(defun magit-iswitchb-completing-read (prompt choices &optional predicate require-match
+                                              initial-input hist def)
+  "iswitchb-based completing-read almost-replacement."
+  (require 'iswitchb)
+  (let ((iswitchb-make-buflist-hook
+         (lambda ()
+           (setq iswitchb-temp-buflist (if (consp (first choices))
+                                           (mapcar #'car choices)
+                                         choices)))))
+    (iswitchb-read-buffer prompt (or initial-input def) require-match)))
+
+(defun magit-ido-completing-read (prompt choices &optional predicate require-match initial-input hist def)
+  "ido-based completing-read almost-replacement."
+  (require 'ido)
+  (let ((selected (ido-completing-read prompt (if (consp (first choices))
+                                                  (mapcar #'car choices)
+                                                choices)
+                                       predicate require-match initial-input hist def)))
+    (if (consp (first choices))
+        (or (cdr (assoc selected choices))
+            selected)
+      selected)))
+
+(defun magit-builtin-completing-read (prompt choices &optional predicate require-match
+                                             initial-input hist def)
+  "Magit wrapper for standard `completing-read' function."
+  (completing-read (if (and def (> (length prompt) 2)
+                            (string-equal ": " (substring prompt -2)))
+                       (format "%s (default %s): " (substring prompt 0 -2) def)
+                     prompt)
+                   choices predicate require-match initial-input hist def))
+
+(defun magit-completing-read (prompt choices &optional predicate require-match
+                                     initial-input hist def)
+  (funcall magit-completing-read-function prompt choices predicate require-match
+           initial-input hist def))
+
+(defun magit-use-region-p ()
+  (if (fboundp 'use-region-p)
+      (use-region-p)
+    (and transient-mark-mode mark-active)))
+
+(defun magit-goto-line (line)
+  "Like `goto-line' but doesn't set the mark."
+  (save-restriction
+    (widen)
+    (goto-char 1)
+    (forward-line (1- line))))
+
+(defun magit-trim-line (str)
+  (if (string= str "")
+      nil
+    (if (equal (elt str (- (length str) 1)) ?\n)
+        (substring str 0 (- (length str) 1))
+      str)))
+
+(defun magit-split-lines (str)
+  (if (string= str "")
+      nil
+    (let ((lines (nreverse (split-string str "\n"))))
+      (if (string= (car lines) "")
+          (setq lines (cdr lines)))
+      (nreverse lines))))
+
+(defun magit-git-insert (args)
+  (insert (magit-git-output args)))
+
+(defun magit-git-output (args)
+  (magit-cmd-output magit-git-executable (append magit-git-standard-options args)))
+
+(defun magit-cmd-insert (cmd args)
+  (insert (magit-cmd-output cmd args)))
+
+(defun magit-cmd-output (cmd args)
+  (let ((cmd-output (with-output-to-string
+                      (with-current-buffer standard-output
+                        (apply #'process-file
+                               cmd
+                               nil (list t nil) nil
+                               args)))))
+    (replace-regexp-in-string "\e\\[.*?m" "" cmd-output)))
+
+(defun magit-git-string (&rest args)
+  (magit-trim-line (magit-git-output args)))
+
+(defun magit-git-lines (&rest args)
+  (magit-split-lines (magit-git-output args)))
+
+(defun magit-git-exit-code (&rest args)
+  (apply #'process-file magit-git-executable nil nil nil
+         (append magit-git-standard-options args)))
+
+(defun magit-file-lines (file)
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (let ((rev (nreverse (split-string (buffer-string) "\n"))))
+        (nreverse (if (equal (car rev) "")
+                      (cdr rev)
+                    rev))))))
+
+(defun magit-write-file-lines (file lines)
+  (with-temp-buffer
+    (dolist (l lines)
+      (insert l "\n"))
+    (write-file file)))
+
+(defun magit-get (&rest keys)
+  "Return the value of Git config entry specified by KEYS."
+  (magit-git-string "config" (mapconcat 'identity keys ".")))
+
+(defun magit-get-all (&rest keys)
+  "Return all values of the Git config entry specified by KEYS."
+  (magit-git-lines "config" "--get-all" (mapconcat 'identity keys ".")))
+
+(defun magit-get-boolean (&rest keys)
+  "Return the boolean value of Git config entry specified by KEYS."
+  (equal (magit-git-string "config" "--bool" (mapconcat 'identity keys "."))
+         "true"))
+
+(defun magit-set (val &rest keys)
+  "Set Git config settings specified by KEYS to VAL."
+  (if val
+      (magit-git-string "config" (mapconcat 'identity keys ".") val)
+    (magit-git-string "config" "--unset" (mapconcat 'identity keys "."))))
+
+(defun magit-remove-conflicts (alist)
+  (let ((dict (make-hash-table :test 'equal))
+        (result nil))
+    (dolist (a alist)
+      (puthash (car a) (cons (cdr a) (gethash (car a) dict))
+               dict))
+    (maphash (lambda (key value)
+               (if (= (length value) 1)
+                   (push (cons key (car value)) result)
+                 (let ((sub (magit-remove-conflicts
+                             (mapcar (lambda (entry)
+                                       (let ((dir (directory-file-name
+                                                   (substring entry 0 (- (length key))))))
+                                         (cons (concat (file-name-nondirectory dir) "/" key)
+                                               entry)))
+                                     value))))
+                   (setq result (append result sub)))))
+             dict)
+    result))
+
+(defun magit-git-repo-p (dir)
+  (file-exists-p (expand-file-name ".git" dir)))
+
+(defun magit-git-dir ()
+  "Returns the .git directory for the current repository."
+  (concat (expand-file-name (magit-git-string "rev-parse" "--git-dir")) "/"))
+
+(defun magit-no-commit-p ()
+  "Return non-nil if there is no commit in the current git repository."
+  (not (magit-git-string
+        "rev-list" "HEAD" "--max-count=1")))
+
+(defun magit-list-repos* (dir level)
+  (if (magit-git-repo-p dir)
+      (list dir)
+    (apply #'append
+           (mapcar (lambda (entry)
+                     (unless (or (string= (substring entry -3) "/..")
+                                 (string= (substring entry -2) "/."))
+                       (magit-list-repos* entry (+ level 1))))
+                   (and (file-directory-p dir)
+                        (< level magit-repo-dirs-depth)
+                        (directory-files dir t nil t))))))
+
+(defun magit-list-repos (dirs)
+  (magit-remove-conflicts
+   (apply #'append
+          (mapcar (lambda (dir)
+                    (mapcar #'(lambda (repo)
+                                (cons (file-name-nondirectory repo)
+                                      repo))
+                            (magit-list-repos* dir 0)))
+                  dirs))))
+
+(defun magit-get-top-dir (cwd)
+  (let ((cwd (expand-file-name (file-truename cwd))))
+    (when (file-directory-p cwd)
+      (let* ((default-directory (file-name-as-directory cwd))
+             (cdup (magit-git-string "rev-parse" "--show-cdup")))
+        (when cdup
+          (file-name-as-directory (expand-file-name cdup cwd)))))))
+
+(defun magit-get-ref (ref)
+  (magit-git-string "symbolic-ref" "-q" ref))
+
+(defun magit-get-current-branch ()
+  (let* ((head (magit-get-ref "HEAD"))
+         (pos (and head (string-match "^refs/heads/" head))))
+    (if pos
+        (substring head 11)
+      nil)))
+
+(defun magit-get-remote (branch)
+  "Return the name of the remote for BRANCH.
+If branch is nil or it has no remote, but a remote named
+\"origin\" exists, return that. Otherwise, return nil."
+  (let ((remote (or (and branch (magit-get "branch" branch "remote"))
+                    (and (magit-get "remote" "origin" "url") "origin"))))
+    (if (string= remote "") nil remote)))
+
+(defun magit-get-current-remote ()
+  "Return the name of the remote for the current branch.
+If there is no current branch, or no remote for that branch,
+but a remote named \"origin\" is configured, return that.
+Otherwise, return nil."
+  (magit-get-remote (magit-get-current-branch)))
+
+(defun magit-ref-exists-p (ref)
+  (= (magit-git-exit-code "show-ref" "--verify" ref) 0))
+
+(defun magit-read-top-dir (dir)
+  "Ask the user for a Git repository.  The choices offered by
+auto-completion will be the repositories under `magit-repo-dirs'.
+If `magit-repo-dirs' is nil or DIR is non-nill, then
+autocompletion will offer directory names."
+  (if (and (not dir) magit-repo-dirs)
+      (let* ((repos (magit-list-repos magit-repo-dirs))
+             (reply (magit-completing-read "Git repository: " repos)))
+        (file-name-as-directory
+         (or (cdr (assoc reply repos))
+             (if (file-directory-p reply)
+                 (expand-file-name reply)
+               (error "Not a repository or a directory: %s" reply)))))
+    (file-name-as-directory
+     (read-directory-name "Git repository: "
+                          (or (magit-get-top-dir default-directory)
+                              default-directory)))))
+
+(defun magit-rev-parse (ref)
+  "Return the SHA hash for REF."
+  (magit-git-string "rev-parse" ref))
+
+(defun magit-ref-ambiguous-p (ref)
+  "Return whether or not REF is ambiguous."
+  ;; If REF is ambiguous, rev-parse just prints errors,
+  ;; so magit-git-string returns nil.
+  (not (magit-git-string "rev-parse" "--abbrev-ref" ref)))
+
+(defun magit-name-rev (rev &optional no-trim)
+  "Return a human-readable name for REV.
+Unlike git name-rev, this will remove tags/ and remotes/ prefixes
+if that can be done unambiguously (unless optional arg NO-TRIM is
+non-nil).  In addition, it will filter out revs involving HEAD."
+  (when rev
+    (let ((name (magit-git-string "name-rev" "--no-undefined" "--name-only" rev)))
+      ;; There doesn't seem to be a way of filtering HEAD out from name-rev,
+      ;; so we have to do it manually.
+      ;; HEAD-based names are too transient to allow.
+      (when (and (stringp name)
+                 (string-match "^\\(.*\\<HEAD\\)\\([~^].*\\|$\\)" name))
+        (let ((head-ref (match-string 1 name))
+              (modifier (match-string 2 name)))
+          ;; Sometimes when name-rev gives a HEAD-based name,
+          ;; rev-parse will give an actual branch or remote name.
+          (setq name (concat (magit-git-string "rev-parse" "--abbrev-ref" head-ref)
+                             modifier))
+          ;; If rev-parse doesn't give us what we want, just use the SHA.
+          (when (or (null name) (string-match-p "\\<HEAD\\>" name))
+            (setq name (magit-rev-parse rev)))))
+      (setq rev (or name rev))
+      (when (string-match "^\\(?:tags\\|remotes\\)/\\(.*\\)" rev)
+        (let ((plain-name (match-string 1 rev)))
+          (unless (or no-trim (magit-ref-ambiguous-p plain-name))
+            (setq rev plain-name))))
+      rev)))
+
+(defun magit-highlight-line-whitespace ()
+  (when (and magit-highlight-whitespace
+             (or (derived-mode-p 'magit-status-mode)
+                 (not (eq magit-highlight-whitespace 'status))))
+    (if (and magit-highlight-trailing-whitespace
+             (looking-at "^[-+].*?\\([ \t]+\\)$"))
+        (overlay-put (make-overlay (match-beginning 1) (match-end 1))
+                     'face 'magit-whitespace-warning-face))
+    (if (or (and (eq magit-current-indentation 'tabs)
+                 (looking-at "^[-+]\\( *\t[ \t]*\\)"))
+            (and (integerp magit-current-indentation)
+                 (looking-at (format "^[-+]\\([ \t]* \\{%s,\\}[ \t]*\\)"
+                                     magit-current-indentation))))
+        (overlay-put (make-overlay (match-beginning 1) (match-end 1))
+                     'face 'magit-whitespace-warning-face))))
+
+(defun magit-put-line-property (prop val)
+  (put-text-property (line-beginning-position) (line-beginning-position 2)
+                     prop val))
+
+(defun magit-format-commit (commit format)
+  (magit-git-string "log" "--max-count=1"
+                    (concat "--pretty=format:" format)
+                    commit))
+
+(defun magit-current-line ()
+  (buffer-substring-no-properties (line-beginning-position)
+                                  (line-end-position)))
+
+(defun magit-insert-region (beg end buf)
+  (let ((text (buffer-substring-no-properties beg end)))
+    (with-current-buffer buf
+      (insert text))))
+
+(defun magit-insert-current-line (buf)
+  (let ((text (buffer-substring-no-properties
+               (line-beginning-position) (line-beginning-position 2))))
+    (with-current-buffer buf
+      (insert text))))
+
+(defun magit-file-uptodate-p (file)
+  (eq (magit-git-exit-code "diff" "--quiet" "--" file) 0))
+
+(defun magit-anything-staged-p ()
+  (not (eq (magit-git-exit-code "diff" "--quiet" "--cached") 0)))
+
+(defun magit-everything-clean-p ()
+  (and (not (magit-anything-staged-p))
+       (eq (magit-git-exit-code "diff" "--quiet") 0)))
+
+(defun magit-commit-parents (commit)
+  (cdr (split-string (magit-git-string "rev-list" "-1" "--parents" commit))))
+
+;; XXX - let the user choose the parent
+
+(defun magit-choose-parent-id (commit op)
+  (let* ((parents (magit-commit-parents commit)))
+    (if (> (length parents) 1)
+        (error "Can't %s merge commits" op)
+      nil)))
+
+;;; Revisions and ranges
+
+(defvar magit-current-range nil
+  "The range described by the current buffer.
+This is only non-nil in diff and log buffers.
+
+This has three possible (non-nil) forms.  If it's a string REF or
+a singleton list (REF), then the range is from REF to the current
+working directory state (or HEAD in a log buffer).  If it's a
+pair (START . END), then the range is START..END.")
+(make-variable-buffer-local 'magit-current-range)
+
+(defun magit-list-interesting-refs (&optional uninteresting)
+  "Return interesting references as given by `git show-ref'.
+Removes references matching UNINTERESTING from the
+results. UNINTERESTING can be either a function taking a single
+argument or a list of strings used as regexps."
+  (let ((refs ()))
+    (dolist (line (magit-git-lines "show-ref"))
+      (if (string-match "[^ ]+ +\\(.*\\)" line)
+          (let ((ref (match-string 1 line)))
+            (cond ((and (functionp uninteresting)
+                        (funcall uninteresting ref)))
+                  ((and (not (functionp uninteresting))
+                        (loop for i in uninteresting thereis (string-match i ref))))
+                  (t
+                   (let ((fmt-ref (magit-format-ref ref)))
+                     (when fmt-ref
+                       (push (cons fmt-ref
+                                   (replace-regexp-in-string "^refs/heads/"
+                                                             "" ref))
+                             refs))))))))
+    (nreverse refs)))
+
+(defun magit-format-ref (ref)
+  "Convert fully-specified ref REF into its displayable form
+according to `magit-remote-ref-format'"
+  (cond
+   ((null ref)
+    nil)
+   ((string-match "refs/heads/\\(.*\\)" ref)
+    (match-string 1 ref))
+   ((string-match "refs/tags/\\(.*\\)" ref)
+    (format (if (eq magit-remote-ref-format 'branch-then-remote)
+                "%s (tag)"
+              "%s")
+            (match-string 1 ref)))
+   ((string-match "refs/remotes/\\([^/]+\\)/\\(.+\\)" ref)
+    (if (eq magit-remote-ref-format 'branch-then-remote)
+        (format "%s (%s)"
+                (match-string 2 ref)
+                (match-string 1 ref))
+      (format "%s/%s"
+              (match-string 1 ref)
+              (match-string 2 ref))))))
+
+(defun magit-tree-contents (treeish)
+  "Returns a list of all files under TREEISH.  TREEISH can be a tree,
+a commit, or any reference to one of those."
+  (let ((return-value nil))
+    (with-temp-buffer
+      (magit-git-insert (list "ls-tree" "-r" treeish))
+      (if (eql 0 (buffer-size))
+          (error "%s is not a commit or tree." treeish))
+      (goto-char (point-min))
+      (while (search-forward-regexp "\t\\(.*\\)" nil 'noerror)
+        (push (match-string 1) return-value)))
+    return-value))
+
+(defvar magit-uninteresting-refs '("refs/remotes/\\([^/]+\\)/HEAD$" "refs/stash"))
+
+(defun magit-read-file-from-rev (revision)
+  (magit-completing-read (format "Retrieve file from %s: " revision)
+                         (magit-tree-contents revision)
+                         nil
+                         'require-match
+                         nil
+                         'magit-read-file-hist
+                         (if buffer-file-name
+                             (let ((topdir-length (length (magit-get-top-dir default-directory))))
+                               (substring (buffer-file-name) topdir-length)))))
+
+(defun magit-read-rev (prompt &optional default uninteresting)
+  (let* ((interesting-refs (magit-list-interesting-refs
+                            (or uninteresting magit-uninteresting-refs)))
+         (reply (magit-completing-read (concat prompt ": ") interesting-refs
+                                       nil nil nil 'magit-read-rev-history default))
+         (rev (or (cdr (assoc reply interesting-refs)) reply)))
+    (if (string= rev "")
+        nil
+      rev)))
+
+(defun magit-read-rev-range (op &optional def-beg def-end)
+  (let ((beg (magit-read-rev (format "%s start" op)
+                             def-beg)))
+    (if (not beg)
+        nil
+      (save-match-data
+        (if (string-match "^\\(.+\\)\\.\\.\\(.+\\)$" beg)
+            (cons (match-string 1 beg) (match-string 2 beg))
+          (let ((end (magit-read-rev (format "%s end" op) def-end)))
+            (cons beg end)))))))
+
+(defun magit-rev-to-git (rev)
+  (or rev
+      (error "No revision specified"))
+  (if (string= rev ".")
+      (magit-marked-commit)
+    rev))
+
+(defun magit-rev-range-to-git (range)
+  (or range
+      (error "No revision range specified"))
+  (if (stringp range)
+      range
+    (if (cdr range)
+        (format "%s..%s"
+                (magit-rev-to-git (car range))
+                (magit-rev-to-git (cdr range)))
+      (format "%s" (magit-rev-to-git (car range))))))
+
+(defun magit-rev-describe (rev)
+  (or rev
+      (error "No revision specified"))
+  (if (string= rev ".")
+      "mark"
+    (magit-name-rev rev)))
+
+(defun magit-rev-range-describe (range things)
+  (or range
+      (error "No revision range specified"))
+  (if (stringp range)
+      (format "%s in %s" things range)
+    (if (cdr range)
+        (format "%s from %s to %s" things
+                (magit-rev-describe (car range))
+                (magit-rev-describe (cdr range)))
+      (format "%s at %s" things (magit-rev-describe (car range))))))
+
+(defun magit-default-rev (&optional no-trim)
+  (or (magit-name-rev (magit-commit-at-point t) no-trim)
+      (let ((branch (magit-guess-branch)))
+        (if branch
+            (if (string-match "^refs/\\(.*\\)" branch)
+                (match-string 1 branch)
+              branch)))))
+
+(defun magit-read-remote (&optional prompt def)
+  "Read the name of a remote.
+PROMPT is used as the prompt, and defaults to \"Remote\".
+DEF is the default value."
+  (let* ((prompt (or prompt "Remote"))
+         (def (or def (magit-guess-remote)))
+         (remotes (magit-git-lines "remote"))
+
+         (reply (magit-completing-read (concat prompt ": ") remotes
+                                       nil nil nil nil def)))
+    (if (string= reply "") nil reply)))
+
+(defun magit-read-remote-branch (remote &optional prompt default)
+  (let* ((prompt (or prompt (format "Remote branch (in %s)" remote)))
+         (branches (delete nil
+                           (mapcar
+                            (lambda (b)
+                              (and (not (string-match " -> " b))
+                                   (string-match (format "^ *%s/\\(.*\\)$"
+                                                         (regexp-quote remote)) b)
+                                   (match-string 1 b)))
+                            (magit-git-lines "branch" "-r"))))
+         (reply (magit-completing-read (concat prompt ": ") branches
+                                       nil nil nil nil default)))
+    (if (string= reply "") nil reply)))
+
+;;; Sections
+
+;; A buffer in magit-mode is organized into hierarchical sections.
+;; These sections are used for navigation and for hiding parts of the
+;; buffer.
+;;
+;; Most sections also represent the objects that Magit works with,
+;; such as files, diffs, hunks, commits, etc.  The 'type' of a section
+;; identifies what kind of object it represents (if any), and the
+;; parent and grand-parent, etc provide the context.
+
+(defstruct magit-section
+  parent title beginning end children hidden type info
+  needs-refresh-on-show)
+
+(defvar magit-top-section nil
+  "The top section of the current buffer.")
+(make-variable-buffer-local 'magit-top-section)
+(put 'magit-top-section 'permanent-local t)
+
+(defvar magit-old-top-section nil)
+
+(defvar magit-section-hidden-default nil)
+
+(defun magit-new-section (title type)
+  "Create a new section with title TITLE and type TYPE in current buffer.
+
+If not `magit-top-section' exist, the new section will be the new top-section
+otherwise, the new-section will be a child of the current top-section.
+
+If TYPE is nil, the section won't be highlighted."
+  (let* ((s (make-magit-section :parent magit-top-section
+                                :title title
+                                :type type
+                                :hidden magit-section-hidden-default))
+         (old (and magit-old-top-section
+                   (magit-find-section (magit-section-path s)
+                                       magit-old-top-section))))
+    (if magit-top-section
+        (push s (magit-section-children magit-top-section))
+      (setq magit-top-section s))
+    (if old
+        (setf (magit-section-hidden s) (magit-section-hidden old)))
+    s))
+
+(defun magit-cancel-section (section)
+  "Delete the section SECTION."
+  (delete-region (magit-section-beginning section)
+                 (magit-section-end section))
+  (let ((parent (magit-section-parent section)))
+    (if parent
+        (setf (magit-section-children parent)
+              (delq section (magit-section-children parent)))
+      (setq magit-top-section nil))))
+
+(defmacro magit-with-section (title type &rest body)
+  "Create a new section of title TITLE and type TYPE and evaluate BODY there.
+
+Sections created inside BODY will become children of the new
+section. BODY must leave point at the end of the created section.
+
+If TYPE is nil, the section won't be highlighted."
+  (declare (indent 2))
+  (let ((s (make-symbol "*section*")))
+    `(let* ((,s (magit-new-section ,title ,type))
+            (magit-top-section ,s))
+       (setf (magit-section-beginning ,s) (point))
+       ,@body
+       (setf (magit-section-end ,s) (point))
+       (setf (magit-section-children ,s)
+             (nreverse (magit-section-children ,s)))
+       ,s)))
+
+(defun magit-set-section (title type start end)
+  "Create a new section of title TITLE and type TYPE with specified start and
+end positions."
+  (let ((section (magit-new-section title type)))
+    (setf (magit-section-beginning section) start)
+    (setf (magit-section-end section) end)
+    section))
+
+(defun magit-set-section-info (info &optional section)
+  (setf (magit-section-info (or section magit-top-section)) info))
+
+(defun magit-set-section-needs-refresh-on-show (flag &optional section)
+  (setf (magit-section-needs-refresh-on-show
+         (or section magit-top-section))
+        flag))
+
+(defmacro magit-create-buffer-sections (&rest body)
+  "Empty current buffer of text and Magit's sections, and then evaluate BODY."
+  (declare (indent 0))
+  `(let ((inhibit-read-only t))
+     (erase-buffer)
+     (let ((magit-old-top-section magit-top-section))
+       (setq magit-top-section nil)
+       ,@body
+       (when (null magit-top-section)
+         (magit-with-section 'top nil
+           (insert "(empty)\n")))
+       (magit-propertize-section magit-top-section)
+       (magit-section-set-hidden magit-top-section
+                                 (magit-section-hidden magit-top-section)))))
+
+(defun magit-propertize-section (section)
+  "Add text-property needed for SECTION."
+  (put-text-property (magit-section-beginning section)
+                     (magit-section-end section)
+                     'magit-section section)
+  (dolist (s (magit-section-children section))
+    (magit-propertize-section s)))
+
+(defun magit-find-section (path top)
+  "Find the section at the path PATH in subsection of section TOP."
+  (if (null path)
+      top
+    (let ((secs (magit-section-children top)))
+      (while (and secs (not (equal (car path)
+                                   (magit-section-title (car secs)))))
+        (setq secs (cdr secs)))
+      (and (car secs)
+           (magit-find-section (cdr path) (car secs))))))
+
+(defun magit-section-path (section)
+  "Return the path of SECTION."
+  (if (not (magit-section-parent section))
+      '()
+    (append (magit-section-path (magit-section-parent section))
+            (list (magit-section-title section)))))
+
+(defun magit-find-section-after (pos)
+  "Find the first section that begins after POS."
+  (magit-find-section-after* pos (list magit-top-section)))
+
+(defun magit-find-section-after* (pos secs)
+  "Find the first section that begins after POS in the list SECS
+\(including children of sections in SECS)."
+  (while (and secs
+              (<= (magit-section-beginning (car secs)) pos))
+    (setq secs (if (magit-section-hidden (car secs))
+                   (cdr secs)
+                 (append (magit-section-children (car secs))
+                         (cdr secs)))))
+  (car secs))
+
+(defun magit-find-section-before (pos)
+  "Return the last section that begins before POS."
+  (let ((section (magit-find-section-at pos)))
+    (do* ((current (or (magit-section-parent section)
+                       section)
+                   next)
+          (next (if (not (magit-section-hidden current))
+                    (magit-find-section-before* pos (magit-section-children current)))
+                (if (not (magit-section-hidden current))
+                    (magit-find-section-before* pos (magit-section-children current)))))
+        ((null next) current))))
+
+(defun magit-find-section-before* (pos secs)
+  "Find the last section that begins before POS in the list SECS."
+  (let ((prev nil))
+    (while (and secs
+                (< (magit-section-beginning (car secs)) pos))
+      (setq prev (car secs))
+      (setq secs (cdr secs)))
+    prev))
+
+(defun magit-current-section ()
+  "Return the Magit section at point."
+  (magit-find-section-at (point)))
+
+(defun magit-find-section-at (pos)
+  "Return the Magit section at POS."
+  (or (get-text-property pos 'magit-section)
+      magit-top-section))
+
+(defun magit-insert-section (section-title-and-type
+                             buffer-title washer cmd &rest args)
+  "Run CMD and put its result in a new section.
+
+SECTION-TITLE-AND-TYPE is either a string that is the title of the section
+or (TITLE . TYPE) where TITLE is the title of the section and TYPE is its type.
+
+If there is no type, or if type is nil, the section won't be highlighted.
+
+BUFFER-TITLE is the inserted title of the section
+
+WASHER is a function that will be run after CMD.
+The buffer will be narrowed to the inserted text.
+It should add sectioning as needed for Magit interaction.
+
+CMD is an external command that will be run with ARGS as arguments."
+  (let* ((body-beg nil)
+         (section-title (if (consp section-title-and-type)
+                            (car section-title-and-type)
+                          section-title-and-type))
+         (section-type (if (consp section-title-and-type)
+                           (cdr section-title-and-type)
+                         nil))
+         (section
+          (magit-with-section section-title section-type
+            (if buffer-title
+                (insert (propertize buffer-title 'face 'magit-section-title)
+                        "\n"))
+            (setq body-beg (point))
+            (magit-cmd-insert cmd args)
+            (if (not (eq (char-before) ?\n))
+                (insert "\n"))
+            (if washer
+                (save-restriction
+                  (narrow-to-region body-beg (point))
+                  (goto-char (point-min))
+                  (funcall washer)
+                  (goto-char (point-max)))))))
+    (if (= body-beg (point))
+        (magit-cancel-section section)
+      (insert "\n"))
+    section))
+
+(defun magit-git-section (section-title-and-type
+                          buffer-title washer &rest args)
+  "Run git and put its result in a new section.
+
+see `magit-insert-section' for meaning of the arguments"
+  (apply #'magit-insert-section
+         section-title-and-type
+         buffer-title
+         washer
+         magit-git-executable
+         (append magit-git-standard-options args)))
+
+(defun magit-goto-next-section ()
+  "Go to the next section."
+  (interactive)
+  (let ((next (magit-find-section-after (point))))
+    (if next
+        (magit-goto-section next)
+      (message "No next section"))))
+
+(defun magit-goto-previous-section ()
+  "Go to the previous section."
+  (interactive)
+  (if (eq (point) 1)
+      (message "No previous section")
+    (magit-goto-section (magit-find-section-before (point)))))
+
+(defun magit-goto-parent-section ()
+  "Go to the parent section."
+  (interactive)
+  (let ((parent (magit-section-parent (magit-current-section))))
+    (when parent
+      (goto-char (magit-section-beginning parent)))))
+
+(defun magit-goto-next-sibling-section ()
+  "Go to the next sibling section."
+  (interactive)
+  (let* ((initial (point))
+         (section (magit-current-section))
+         (end (- (magit-section-end section) 1))
+         (parent (magit-section-parent section))
+         (siblings (magit-section-children parent))
+         (next-sibling (magit-find-section-after* end siblings)))
+    (if next-sibling
+        (magit-goto-section next-sibling)
+      (magit-goto-next-section))))
+
+(defun magit-goto-previous-sibling-section ()
+  "Go to the previous sibling section."
+  (interactive)
+  (let* ((section (magit-current-section))
+         (beginning (magit-section-beginning section))
+         (parent (magit-section-parent section))
+         (siblings (magit-section-children parent))
+         (previous-sibling (magit-find-section-before* beginning siblings)))
+    (if previous-sibling
+        (magit-goto-section previous-sibling)
+      (magit-goto-parent-section))))
+
+(defun magit-goto-section (section)
+  (goto-char (magit-section-beginning section))
+  (cond
+   ((and magit-log-auto-more
+         (eq (magit-section-type section) 'longer))
+    (magit-log-show-more-entries)
+    (forward-line -1)
+    (magit-goto-next-section))
+   ((and (eq (magit-section-type section) 'commit)
+         (derived-mode-p 'magit-log-mode))
+    (magit-show-commit section))))
+
+(defun magit-goto-section-at-path (path)
+  "Go to the section described by PATH."
+  (let ((sec (magit-find-section path magit-top-section)))
+    (if sec
+        (goto-char (magit-section-beginning sec))
+      (message "No such section"))))
+
+(defun magit-for-all-sections (func &optional top)
+  "Run FUNC on TOP and recursively on all its children.
+
+Default value for TOP is `magit-top-section'"
+  (let ((section (or top magit-top-section)))
+    (when section
+      (funcall func section)
+      (dolist (c (magit-section-children section))
+        (magit-for-all-sections func c)))))
+
+(defun magit-section-set-hidden (section hidden)
+  "Hide SECTION if HIDDEN is not nil, show it otherwise."
+  (setf (magit-section-hidden section) hidden)
+  (if (and (not hidden)
+           (magit-section-needs-refresh-on-show section))
+      (magit-refresh)
+    (let ((inhibit-read-only t)
+          (beg (save-excursion
+                 (goto-char (magit-section-beginning section))
+                 (forward-line)
+                 (point)))
+          (end (magit-section-end section)))
+      (if (< beg end)
+          (put-text-property beg end 'invisible hidden)))
+    (if (not hidden)
+        (dolist (c (magit-section-children section))
+          (magit-section-set-hidden c (magit-section-hidden c))))))
+
+(defun magit-section-any-hidden (section)
+  "Return true if SECTION or any of its children is hidden."
+  (or (magit-section-hidden section)
+      (let ((kids (magit-section-children section)))
+        (while (and kids (not (magit-section-any-hidden (car kids))))
+          (setq kids (cdr kids)))
+        kids)))
+
+(defun magit-section-collapse (section)
+  "Show SECTION and hide all its children."
+  (dolist (c (magit-section-children section))
+    (setf (magit-section-hidden c) t))
+  (magit-section-set-hidden section nil))
+
+(defun magit-section-expand (section)
+  "Show SECTION and all its children."
+  (dolist (c (magit-section-children section))
+    (setf (magit-section-hidden c) nil))
+  (magit-section-set-hidden section nil))
+
+(defun magit-section-expand-all-aux (section)
+  "Show recursively all SECTION's children."
+  (dolist (c (magit-section-children section))
+    (setf (magit-section-hidden c) nil)
+    (magit-section-expand-all-aux c)))
+
+(defun magit-section-expand-all (section)
+  "Show SECTION and all its children."
+  (magit-section-expand-all-aux section)
+  (magit-section-set-hidden section nil))
+
+(defun magit-section-hideshow (flag-or-func)
+  "Show or hide current section depending on FLAG-OR-FUNC.
+
+If FLAG-OR-FUNC is a function, it will be ran on current section
+IF FLAG-OR-FUNC is a Boolean value, the section will be hidden if its true, shown otherwise"
+  (let ((section (magit-current-section)))
+    (when (magit-section-parent section)
+      (goto-char (magit-section-beginning section))
+      (if (functionp flag-or-func)
+          (funcall flag-or-func section)
+        (magit-section-set-hidden section flag-or-func)))))
+
+(defun magit-show-section ()
+  "Show current section."
+  (interactive)
+  (magit-section-hideshow nil))
+
+(defun magit-hide-section ()
+  "Hide current section."
+  (interactive)
+  (magit-section-hideshow t))
+
+(defun magit-collapse-section ()
+  "Hide all subsection of current section."
+  (interactive)
+  (magit-section-hideshow #'magit-section-collapse))
+
+(defun magit-expand-section ()
+  "Show all subsection of current section."
+  (interactive)
+  (magit-section-hideshow #'magit-section-expand))
+
+(defun magit-toggle-file-section ()
+  "Like `magit-toggle-section' but toggle at file granularity."
+  (interactive)
+  (when (eq 'hunk (first (magit-section-context-type (magit-current-section))))
+    (magit-goto-parent-section))
+  (magit-toggle-section))
+
+(defun magit-toggle-section ()
+  "Toggle hidden status of current section."
+  (interactive)
+  (magit-section-hideshow
+   (lambda (s)
+     (magit-section-set-hidden s (not (magit-section-hidden s))))))
+
+(defun magit-expand-collapse-section ()
+  "Toggle hidden status of subsections of current section."
+  (interactive)
+  (magit-section-hideshow
+   (lambda (s)
+     (cond ((magit-section-any-hidden s)
+            (magit-section-expand-all s))
+           (t
+            (magit-section-collapse s))))))
+
+(defun magit-cycle-section ()
+  "Cycle between expanded, hidden and collapsed state for current section.
+
+Hidden: only the first line of the section is shown
+Collapsed: only the first line of the subsection is shown
+Expanded: everything is shown."
+  (interactive)
+  (magit-section-hideshow
+   (lambda (s)
+     (cond ((magit-section-hidden s)
+            (magit-section-collapse s))
+           ((notany #'magit-section-hidden (magit-section-children s))
+            (magit-section-set-hidden s t))
+           (t
+            (magit-section-expand s))))))
+
+(defun magit-section-lineage (s)
+  "Return list of parent, grand-parents... for section S."
+  (when s
+    (cons s (magit-section-lineage (magit-section-parent s)))))
+
+(defun magit-section-show-level (section level threshold path)
+  (magit-section-set-hidden section (>= level threshold))
+  (when (and (< level threshold)
+             (not (magit-no-commit-p)))
+    (if path
+        (magit-section-show-level (car path) (1+ level) threshold (cdr path))
+      (dolist (c (magit-section-children section))
+        (magit-section-show-level c (1+ level) threshold nil)))))
+
+(defun magit-show-level (level all)
+  "Show section whose level is less than LEVEL, hide the others.
+If ALL is non nil, do this in all sections,
+otherwise do it only on ancestors and descendants of current section."
+  (magit-with-refresh
+    (if all
+        (magit-section-show-level magit-top-section 0 level nil)
+      (let ((path (reverse (magit-section-lineage (magit-current-section)))))
+        (magit-section-show-level (car path) 0 level (cdr path))))))
+
+(defun magit-show-only-files ()
+  "Show section that are files, but not there subsection.
+
+Do this in on ancestors and descendants of current section."
+  (interactive)
+  (if (derived-mode-p 'magit-status-mode)
+      (call-interactively 'magit-show-level-2)
+    (call-interactively 'magit-show-level-1)))
+
+(defun magit-show-only-files-all ()
+  "Show section that are files, but not there subsection.
+
+Do this for all sections"
+  (interactive)
+  (if (derived-mode-p 'magit-status-mode)
+      (call-interactively 'magit-show-level-2-all)
+    (call-interactively 'magit-show-level-1-all)))
+
+(defmacro magit-define-level-shower-1 (level all)
+  "Define an interactive function to show function of level LEVEL.
+
+If ALL is non nil, this function will affect all section,
+otherwise it will affect only ancestors and descendants of current section."
+  (let ((fun (intern (format "magit-show-level-%s%s"
+                             level (if all "-all" ""))))
+        (doc (format "Show sections on level %s." level)))
+    `(defun ,fun ()
+       ,doc
+       (interactive)
+       (magit-show-level ,level ,all))))
+
+(defmacro magit-define-level-shower (level)
+  "Define two interactive function to show function of level LEVEL.
+one for all, one for current lineage."
+  `(progn
+     (magit-define-level-shower-1 ,level nil)
+     (magit-define-level-shower-1 ,level t)))
+
+(defmacro magit-define-section-jumper (sym title)
+  "Define an interactive function to go to section SYM.
+
+TITLE is the displayed title of the section."
+  (let ((fun (intern (format "magit-jump-to-%s" sym)))
+        (doc (format "Jump to section `%s'." title)))
+    `(progn
+       (defun ,fun ()
+         ,doc
+         (interactive)
+         (magit-goto-section-at-path '(,sym)))
+       (put ',fun 'definition-name ',sym))))
+
+(defmacro magit-define-inserter (sym arglist &rest body)
+  (declare (indent defun))
+  (let ((fun (intern (format "magit-insert-%s" sym)))
+        (before (intern (format "magit-before-insert-%s-hook" sym)))
+        (after (intern (format "magit-after-insert-%s-hook" sym)))
+        (doc (format "Insert items for `%s'." sym)))
+    `(progn
+       (defvar ,before nil)
+       (defvar ,after nil)
+       (defun ,fun ,arglist
+         ,doc
+         (run-hooks ',before)
+         ,@body
+         (run-hooks ',after))
+       (put ',before 'definition-name ',sym)
+       (put ',after 'definition-name ',sym)
+       (put ',fun 'definition-name ',sym))))
+
+(defvar magit-highlighted-section nil)
+
+(defun magit-refine-section (section)
+  "Apply temporary refinements to the display of SECTION.
+Refinements can be undone with `magit-unrefine-section'."
+  (let ((type (and section (magit-section-type section))))
+    (cond ((and (eq type 'hunk)
+                magit-diff-refine-hunk
+                (not (eq magit-diff-refine-hunk 'all)))
+           ;; Refine the current hunk to show fine details, using
+           ;; diff-mode machinery.
+           (save-excursion
+             (goto-char (magit-section-beginning magit-highlighted-section))
+             (diff-refine-hunk))))))
+
+(defun magit-unrefine-section (section)
+  "Remove refinements to the display of SECTION done by `magit-refine-section'."
+  (let ((type (and section (magit-section-type section))))
+    (cond ((and (eq type 'hunk)
+                magit-diff-refine-hunk
+                (not (eq magit-diff-refine-hunk 'all)))
+           ;; XXX this should be in some diff-mode function, like
+           ;; `diff-unrefine-hunk'
+           (remove-overlays (magit-section-beginning section)
+                            (magit-section-end section)
+                            'diff-mode 'fine)))))
+
+(defvar magit-highlight-overlay nil)
+
+(defun magit-highlight-section ()
+  "Highlight current section if it has a type."
+  (let ((section (magit-current-section)))
+    (when (not (eq section magit-highlighted-section))
+      (when magit-highlighted-section
+        ;; remove any refinement from previous hunk
+        (magit-unrefine-section magit-highlighted-section))
+      (setq magit-highlighted-section section)
+      (if (not magit-highlight-overlay)
+          (let ((ov (make-overlay 1 1)))
+            (overlay-put ov 'face 'magit-item-highlight)
+            (setq magit-highlight-overlay ov)))
+      (if (and section (magit-section-type section))
+          (progn
+            (magit-refine-section section)
+            (move-overlay magit-highlight-overlay
+                          (magit-section-beginning section)
+                          (magit-section-end section)
+                          (current-buffer)))
+        (delete-overlay magit-highlight-overlay)))))
+
+(defun magit-section-context-type (section)
+  (if (null section)
+      '()
+    (let ((c (or (magit-section-type section)
+                 (if (symbolp (magit-section-title section))
+                     (magit-section-title section)))))
+      (if c
+          (cons c (magit-section-context-type
+                   (magit-section-parent section)))
+        '()))))
+
+(defun magit-prefix-p (prefix list)
+  "Returns non-nil if PREFIX is a prefix of LIST.  PREFIX and LIST should both be
+lists.
+
+If the car of PREFIX is the symbol '*, then return non-nil if the cdr of PREFIX
+is a sublist of LIST (as if '* matched zero or more arbitrary elements of LIST)"
+  ;;; Very schemish...
+  (or (null prefix)
+      (if (eq (car prefix) '*)
+          (or (magit-prefix-p (cdr prefix) list)
+              (and (not (null list))
+                   (magit-prefix-p prefix (cdr list))))
+        (and (not (null list))
+             (equal (car prefix) (car list))
+             (magit-prefix-p (cdr prefix) (cdr list))))))
+
+(defmacro magit-section-case (head &rest clauses)
+  "Make different action depending of current section.
+
+HEAD is (SECTION INFO &optional OPNAME),
+  SECTION will be bind to the current section,
+  INFO will be bind to the info's of the current section,
+  OPNAME is a string that will be used to describe current action,
+
+CLAUSES is a list of CLAUSE, each clause is (SECTION-TYPE &BODY)
+where SECTION-TYPE describe section where BODY will be run.
+
+This returns non-nil if some section matches. If the
+corresponding body return a non-nil value, it is returned,
+otherwise it returns t.
+
+If no section matches, this returns nil if no OPNAME was given
+and throws an error otherwise."
+  (declare (indent 1))
+  (let ((section (car head))
+        (info (cadr head))
+        (type (make-symbol "*type*"))
+        (context (make-symbol "*context*"))
+        (opname (caddr head)))
+    `(let* ((,section (magit-current-section))
+            (,info (and ,section (magit-section-info ,section)))
+            (,type (and ,section (magit-section-type ,section)))
+            (,context (magit-section-context-type ,section)))
+       (cond ,@(mapcar (lambda (clause)
+                         (if (eq (car clause) t)
+                             `(t (or (progn ,@(cdr clause))
+                                     t))
+                           (let ((prefix (reverse (car clause)))
+                                 (body (cdr clause)))
+                             `((magit-prefix-p ',prefix ,context)
+                               (or (progn ,@body)
+                                   t)))))
+                       clauses)
+             ,@(when opname
+                 `(((run-hook-with-args-until-success
+                     ',(intern (format "magit-%s-action-hook" opname))))
+                   ((not ,type)
+                    (error "Nothing to %s here" ,opname))
+                   (t
+                    (error "Can't %s a %s"
+                           ,opname
+                           (or (get ,type 'magit-description)
+                               ,type)))))))))
+
+(defmacro magit-section-action (head &rest clauses)
+  (declare (indent 1))
+  `(magit-with-refresh
+     (magit-section-case ,head ,@clauses)))
+
+(defmacro magit-add-action (head &rest clauses)
+  "Add additional actions to a pre-existing operator.
+The syntax is identical to `magit-section-case', except that
+OPNAME is mandatory and specifies the operation to which to add
+the actions."
+  (declare (indent 1))
+  (let ((section (car head))
+        (info (cadr head))
+        (type (caddr head)))
+    `(add-hook ',(intern (format "magit-%s-action-hook" type))
+               (lambda ()
+                 ,(macroexpand
+                   ;; Don't pass in the opname so we don't recursively
+                   ;; run the hook again, and so we don't throw an
+                   ;; error if no action matches.
+                   `(magit-section-case (,section ,info)
+                      ,@clauses))))))
+
+(defun magit-wash-sequence (func)
+  "Run FUNC until end of buffer is reached.
+
+FUNC should leave point at the end of the modified region"
+  (while (and (not (eobp))
+              (funcall func))))
+
+(defmacro magit-define-command (sym arglist &rest body)
+  "Macro to define a magit command.
+It will define the magit-SYM function having ARGLIST as argument.
+It will also define the magit-SYM-command-hook variable.
+
+The defined function will call the function in the hook in
+order until one return non nil. If they all return nil then body will be called.
+
+It is used to define hookable magit command: command defined by this
+function can be enriched by magit extension like magit-topgit and magit-svn"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]        ; Match the doc string, if present.
+                           [&optional ("interactive" interactive)]
+                           def-body)))
+  (let ((fun (intern (format "magit-%s" sym)))
+        (hook (intern (format "magit-%s-command-hook" sym)))
+        (doc (format "Command for `%s'." sym))
+        (inter nil)
+        (instr body))
+    (when (stringp (car body))
+      (setq doc (car body)
+            instr (cdr body)))
+    (let ((form (car instr)))
+      (when (eq (car form) 'interactive)
+        (setq inter form
+              instr (cdr instr))))
+    `(progn
+       (defvar ,hook nil)
+       (defun ,fun ,arglist
+         ,doc
+         ,inter
+         (or (run-hook-with-args-until-success
+              ',hook ,@(remq '&optional (remq '&rest arglist)))
+             ,@instr))
+       (put ',fun 'definition-name ',sym)
+       (put ',hook 'definition-name ',sym))))
+
+;;; Running commands
+
+(defun magit-set-mode-line-process (str)
+  (let ((pr (if str (concat " " str) "")))
+    (save-excursion
+      (magit-for-all-buffers (lambda ()
+                               (setq mode-line-process pr))))))
+
+(defun magit-process-indicator-from-command (comps)
+  (if (magit-prefix-p (cons magit-git-executable magit-git-standard-options)
+                      comps)
+      (setq comps (nthcdr (+ (length magit-git-standard-options) 1) comps)))
+  (cond ((or (null (cdr comps))
+             (not (member (car comps) '("remote"))))
+         (car comps))
+        (t
+         (concat (car comps) " " (cadr comps)))))
+
+(defvar magit-process nil)
+(defvar magit-process-client-buffer nil)
+(defvar magit-process-buffer-name "*magit-process*"
+  "Buffer name for running git commands.")
+
+(defun magit-run* (cmd-and-args
+                   &optional logline noerase noerror nowait input)
+  (if (and magit-process
+           (get-buffer magit-process-buffer-name))
+      (error "Git is already running"))
+  (let ((cmd (car cmd-and-args))
+        (args (cdr cmd-and-args))
+        (dir default-directory)
+        (buf (get-buffer-create magit-process-buffer-name))
+        (successp nil))
+    (magit-set-mode-line-process
+     (magit-process-indicator-from-command cmd-and-args))
+    (setq magit-process-client-buffer (current-buffer))
+    (with-current-buffer buf
+      (view-mode 1)
+      (set (make-local-variable 'view-no-disable-on-exit) t)
+      (setq view-exit-action
+            (lambda (buffer)
+              (with-current-buffer buffer
+                (bury-buffer))))
+      (setq buffer-read-only t)
+      (let ((inhibit-read-only t))
+        (setq default-directory dir)
+        (if noerase
+            (goto-char (point-max))
+          (erase-buffer))
+        (insert "$ " (or logline
+                         (mapconcat 'identity cmd-and-args " "))
+                "\n")
+        (cond (nowait
+               (setq magit-process
+                     (let ((process-connection-type magit-process-connection-type))
+                       (apply 'magit-start-process cmd buf cmd args)))
+               (set-process-sentinel magit-process 'magit-process-sentinel)
+               (set-process-filter magit-process 'magit-process-filter)
+               (when input
+                 (with-current-buffer input
+                   (process-send-region magit-process
+                                        (point-min) (point-max)))
+                 (process-send-eof magit-process)
+                 (sit-for 0.1 t))
+               (cond ((= magit-process-popup-time 0)
+                      (pop-to-buffer (process-buffer magit-process)))
+                     ((> magit-process-popup-time 0)
+                      (run-with-timer
+                       magit-process-popup-time nil
+                       (function
+                        (lambda (buf)
+                          (with-current-buffer buf
+                            (when magit-process
+                              (display-buffer (process-buffer magit-process))
+                              (goto-char (point-max))))))
+                       (current-buffer))))
+               (setq successp t))
+              (input
+               (with-current-buffer input
+                 (setq default-directory dir)
+                 (setq magit-process
+                       ;; Don't use a pty, because it would set icrnl
+                       ;; which would modify the input (issue #20).
+                       (let ((process-connection-type nil))
+                         (apply 'magit-start-process cmd buf cmd args)))
+                 (set-process-filter magit-process 'magit-process-filter)
+                 (process-send-region magit-process
+                                      (point-min) (point-max))
+                 (process-send-eof magit-process)
+                 (while (equal (process-status magit-process) 'run)
+                   (sit-for 0.1 t))
+                 (setq successp
+                       (equal (process-exit-status magit-process) 0))
+                 (setq magit-process nil))
+               (magit-set-mode-line-process nil)
+               (magit-need-refresh magit-process-client-buffer))
+              (t
+               (setq successp
+                     (equal (apply 'process-file cmd nil buf nil args) 0))
+               (magit-set-mode-line-process nil)
+               (magit-need-refresh magit-process-client-buffer))))
+      (or successp
+          noerror
+          (error
+           "%s ... [Hit %s or see buffer %s for details]"
+           (or (with-current-buffer (get-buffer magit-process-buffer-name)
+                 (when (re-search-backward
+                        (concat "^error: \\(.*\\)" paragraph-separate) nil t)
+                   (match-string 1)))
+               "Git failed")
+           (with-current-buffer magit-process-client-buffer
+             (key-description (car (where-is-internal
+                                    'magit-display-process))))
+           magit-process-buffer-name))
+      successp)))
+
+(autoload 'dired-uncache "dired")
+(defun magit-process-sentinel (process event)
+  (let ((msg (format "%s %s." (process-name process) (substring event 0 -1)))
+        (successp (string-match "^finished" event))
+        (key (with-current-buffer magit-process-client-buffer
+               (key-description (car (where-is-internal
+                                      'magit-display-process))))))
+    (with-current-buffer (process-buffer process)
+      (let ((inhibit-read-only t))
+        (goto-char (point-max))
+        (insert msg "\n")
+        (message (if successp msg
+                   (format "%s Hit %s or see buffer %s for details."
+                           msg key (current-buffer)))))
+      (unless (memq (process-status process) '(run open))
+        (dired-uncache default-directory)))
+    (setq magit-process nil)
+    (magit-set-mode-line-process nil)
+    (magit-refresh-buffer magit-process-client-buffer)))
+
+(defun magit-password (proc string)
+  "Checks if git/ssh asks for a password and ask the user for it."
+  (let (ask)
+    (cond ((or (string-match "^Enter passphrase for key '\\\(.*\\\)': $" string)
+               (string-match "^\\\(.*\\\)'s password:" string)
+               (string-match "^Password for '\\\(.*\\\)':" string))
+           (setq ask (format "Password for '%s': " (match-string 1 string))))
+          ((string-match "^[pP]assword:" string)
+           (setq ask "Password:")))
+    (when ask
+      (process-send-string proc (concat (read-passwd ask nil) "\n")))))
+
+(defun magit-username (proc string)
+  "Checks if git asks for a username and ask the user for it."
+  (when (string-match "^Username for '\\\(.*\\\)':" string)
+    (process-send-string proc
+                         (concat
+                          (read-string (format "Username for '%s': "
+                                               (match-string 1 string))
+                                       nil nil (user-login-name))
+                          "\n"))))
+
+(defun magit-process-filter (proc string)
+  (save-current-buffer
+    (set-buffer (process-buffer proc))
+    (let ((inhibit-read-only t))
+      (magit-username proc string)
+      (magit-password proc string)
+      (goto-char (process-mark proc))
+      ;; Find last ^M in string.  If one was found, ignore everything
+      ;; before it and delete the current line.
+      (let ((ret-pos (length string)))
+        (while (and (>= (setq ret-pos (1- ret-pos)) 0)
+                    (/= ?\r (aref string ret-pos))))
+        (cond ((>= ret-pos 0)
+               (goto-char (line-beginning-position))
+               (delete-region (point) (line-end-position))
+               (insert (substring string (+ ret-pos 1))))
+              (t
+               (insert string))))
+      (set-marker (process-mark proc) (point)))))
+
+(defun magit-run (cmd &rest args)
+  (magit-with-refresh
+    (magit-run* (cons cmd args))))
+
+(defun magit-run-git (&rest args)
+  (magit-with-refresh
+    (magit-run* (append (cons magit-git-executable
+                              magit-git-standard-options)
+                        args))))
+
+(defun magit-run-git-with-input (input &rest args)
+  (magit-with-refresh
+    (magit-run* (append (cons magit-git-executable
+                              magit-git-standard-options)
+                        args)
+                nil nil nil nil input)))
+
+(defun magit-run-git-async (&rest args)
+  (message "Running %s %s" magit-git-executable (mapconcat 'identity args " "))
+  (magit-run* (append (cons magit-git-executable
+                            magit-git-standard-options)
+                      args)
+              nil nil nil t))
+
+(defun magit-run-async-with-input (input cmd &rest args)
+  (magit-run* (cons cmd args) nil nil nil t input))
+
+(defun magit-display-process ()
+  "Display output from most recent git command."
+  (interactive)
+  (unless (get-buffer magit-process-buffer-name)
+    (error "No Git commands have run"))
+  (display-buffer magit-process-buffer-name))
+
+;;; Mode
+
+;; We define individual functions (instead of using lambda etc) so
+;; that the online help can show something meaningful.
+
+(magit-define-section-jumper untracked "Untracked files")
+(magit-define-section-jumper unstaged  "Unstaged changes")
+(magit-define-section-jumper staged    "Staged changes")
+(magit-define-section-jumper unpushed  "Unpushed commits")
+
+(magit-define-level-shower 1)
+(magit-define-level-shower 2)
+(magit-define-level-shower 3)
+(magit-define-level-shower 4)
+
+(easy-menu-define magit-mode-menu magit-mode-map
+  "Magit menu"
+  '("Magit"
+    ["Refresh" magit-refresh t]
+    ["Refresh all" magit-refresh-all t]
+    "---"
+    ["Stage" magit-stage-item t]
+    ["Stage all" magit-stage-all t]
+    ["Unstage" magit-unstage-item t]
+    ["Unstage all" magit-unstage-all t]
+    ["Commit" magit-log-edit t]
+    ["Add log entry" magit-add-log t]
+    ["Tag" magit-tag t]
+    ["Annotated tag" magit-annotated-tag t]
+    "---"
+    ["Diff working tree" magit-diff-working-tree t]
+    ["Diff" magit-diff t]
+    ("Log"
+     ["Short Log" magit-log t]
+     ["Long Log" magit-log-long t]
+     ["Reflog" magit-reflog t]
+     ["Extended..." magit-key-mode-popup-logging t])
+    "---"
+    ["Cherry pick" magit-cherry-pick-item t]
+    ["Apply" magit-apply-item t]
+    ["Revert" magit-revert-item t]
+    "---"
+    ["Ignore" magit-ignore-item t]
+    ["Ignore locally" magit-ignore-item-locally t]
+    ["Discard" magit-discard-item t]
+    ["Reset head" magit-reset-head t]
+    ["Reset working tree" magit-reset-working-tree t]
+    ["Stash" magit-stash t]
+    ["Snapshot" magit-stash-snapshot t]
+    "---"
+    ["Branch..." magit-checkout t]
+    ["Merge" magit-manual-merge t]
+    ["Interactive resolve" magit-interactive-resolve-item t]
+    ["Rebase" magit-rebase-step t]
+    ("Rewrite"
+     ["Start" magit-rewrite-start t]
+     ["Stop" magit-rewrite-stop t]
+     ["Finish" magit-rewrite-finish t]
+     ["Abort" magit-rewrite-abort t]
+     ["Set used" magit-rewrite-set-used t]
+     ["Set unused" magit-rewrite-set-unused t])
+    "---"
+    ["Push" magit-push t]
+    ["Pull" magit-pull t]
+    ["Remote update" magit-remote-update t]
+    ("Submodule"
+     ["Submodule update" magit-submodule-update t]
+     ["Submodule update and init" magit-submodule-update-init t]
+     ["Submodule init" magit-submodule-init t]
+     ["Submodule sync" magit-submodule-sync t])
+    "---"
+    ("Extensions")
+    "---"
+    ["Display Git output" magit-display-process t]
+    ["Quit Magit" magit-quit-window t]))
+
+(defvar magit-mode-hook nil "Hook run by `magit-mode'.")
+
+(put 'magit-mode 'mode-class 'special)
+
+(defvar magit-refresh-function nil)
+(make-variable-buffer-local 'magit-refresh-function)
+(put 'magit-refresh-function 'permanent-local t)
+
+(defvar magit-refresh-args nil)
+(make-variable-buffer-local 'magit-refresh-args)
+(put 'magit-refresh-args 'permanent-local t)
+
+(defvar last-point)
+
+(defun magit-remember-point ()
+  (setq last-point (point)))
+
+(defun magit-invisible-region-end (pos)
+  (while (and (not (= pos (point-max))) (invisible-p pos))
+    (setq pos (next-char-property-change pos)))
+  pos)
+
+(defun magit-invisible-region-start (pos)
+  (while (and (not (= pos (point-min))) (invisible-p pos))
+    (setq pos (1- (previous-char-property-change pos))))
+  pos)
+
+(defun magit-correct-point-after-command ()
+  "Move point outside of invisible regions.
+
+Emacs often leaves point in invisible regions, it seems.  To fix
+this, we move point ourselves and never let Emacs do its own
+adjustments.
+
+When point has to be moved out of an invisible region, it can be
+moved to its end or its beginning.  We usually move it to its
+end, except when that would move point back to where it was
+before the last command."
+  (if (invisible-p (point))
+      (let ((end (magit-invisible-region-end (point))))
+        (goto-char (if (= end last-point)
+                       (magit-invisible-region-start (point))
+                     end))))
+  (setq disable-point-adjustment t))
+
+(defun magit-post-command-hook ()
+  (magit-correct-point-after-command)
+  (magit-highlight-section))
+
+(defun magit-mode ()
+  "Review the status of a git repository and act on it.
+
+Please see the manual for a complete description of Magit.
+
+\\{magit-mode-map}"
+  (kill-all-local-variables)
+  (buffer-disable-undo)
+  (setq buffer-read-only t
+        truncate-lines t
+        major-mode 'magit-mode
+        mode-name "Magit"
+        mode-line-process "")
+  (add-hook 'pre-command-hook #'magit-remember-point nil t)
+  (add-hook 'post-command-hook #'magit-post-command-hook t t)
+  (use-local-map magit-mode-map)
+  (setq magit-current-indentation (magit-indentation-for default-directory))
+  ;; Emacs' normal method of showing trailing whitespace gives weird
+  ;; results when `magit-whitespace-warning-face' is different from
+  ;; `trailing-whitespace'.
+  (if (and magit-highlight-whitespace magit-highlight-trailing-whitespace)
+      (setq show-trailing-whitespace nil))
+  (run-mode-hooks 'magit-mode-hook))
+
+(defun magit-mode-init (dir submode refresh-func &rest refresh-args)
+  (setq default-directory dir
+        magit-refresh-function refresh-func
+        magit-refresh-args refresh-args)
+  (funcall submode)
+  (magit-refresh-buffer))
+
+(defun magit-indentation-for (dir)
+  (let (result)
+    (dolist (pair magit-highlight-indentation)
+      (if (string-match-p (car pair) dir)
+          (setq result (cdr pair))))
+    result))
+
+(defun magit-find-buffer (submode &optional dir)
+  (let ((topdir (magit-get-top-dir (or dir default-directory))))
+    (dolist (buf (buffer-list))
+      (if (with-current-buffer buf
+            (and (eq major-mode submode)
+                 default-directory
+                 (equal (expand-file-name default-directory) topdir)))
+          (return buf)))))
+
+(defun magit-find-status-buffer (&optional dir)
+  (magit-find-buffer 'magit-status-mode dir))
+
+(defun magit-for-all-buffers (func &optional dir)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (if (and (derived-mode-p 'magit-mode)
+               (or (null dir)
+                   (equal default-directory dir)))
+          (funcall func)))))
+
+(defun magit-refresh-buffer (&optional buffer)
+  (with-current-buffer (or buffer (current-buffer))
+    (let* ((old-line (line-number-at-pos))
+           (old-point (point))
+           (old-section (magit-current-section))
+           (old-path (and old-section
+                          (magit-section-path (magit-current-section)))))
+      (beginning-of-line)
+      (let ((section-line (and old-section
+                               (count-lines
+                                (magit-section-beginning old-section)
+                                (point))))
+            (line-char (- old-point (point))))
+        (if magit-refresh-function
+            (apply magit-refresh-function
+                   magit-refresh-args))
+        (magit-refresh-marked-commits-in-buffer)
+        (let ((s (and old-path (magit-find-section old-path magit-top-section))))
+          (cond (s
+                 (goto-char (magit-section-beginning s))
+                 (forward-line section-line)
+                 (forward-char line-char))
+                (t
+                 (magit-goto-line old-line)))
+          (dolist (w (get-buffer-window-list (current-buffer)))
+            (set-window-point w (point)))
+          (magit-highlight-section))))))
+
+(defun magit-string-has-prefix-p (string prefix)
+  (eq (compare-strings string nil (length prefix) prefix nil nil) t))
+
+(defun magit-revert-buffers (dir &optional ignore-modtime)
+  (dolist (buffer (buffer-list))
+    (when (and buffer
+               (buffer-file-name buffer)
+               ;; don't revert indirect buffers, as the parent will be reverted
+               (not (buffer-base-buffer buffer))
+               (magit-string-has-prefix-p (buffer-file-name buffer) dir)
+               (file-readable-p (buffer-file-name buffer))
+               (or ignore-modtime (not (verify-visited-file-modtime buffer)))
+               (not (buffer-modified-p buffer)))
+      (with-current-buffer buffer
+        (condition-case var
+            (revert-buffer t t nil)
+          (error (let ((signal-data (cadr var)))
+                   (cond (t (magit-bug-report signal-data))))))))))
+
+(defun magit-update-vc-modeline (dir)
+  "Update the modeline for buffers representable by magit."
+  (dolist (buffer (buffer-list))
+    (when (and buffer
+               (buffer-file-name buffer)
+               (magit-string-has-prefix-p (buffer-file-name buffer) dir))
+      (with-current-buffer buffer
+        (condition-case var
+            (vc-find-file-hook)
+          (error (let ((signal-data (cadr var)))
+                   (cond (t (magit-bug-report signal-data))))))))))
+
+(defvar magit-refresh-needing-buffers nil)
+(defvar magit-refresh-pending nil)
+
+(defun magit-refresh-wrapper (func)
+  (if magit-refresh-pending
+      (funcall func)
+    (let* ((dir default-directory)
+           (status-buffer (magit-find-status-buffer dir))
+           (magit-refresh-needing-buffers nil)
+           (magit-refresh-pending t))
+      (unwind-protect
+          (funcall func)
+        (when magit-refresh-needing-buffers
+          (magit-revert-buffers dir)
+          (dolist (b (adjoin status-buffer
+                             magit-refresh-needing-buffers))
+            (magit-refresh-buffer b)))))))
+
+(defun magit-need-refresh (&optional buffer)
+  "Mark BUFFER as needing to be refreshed.  If BUFFER is nil, use the
+current buffer."
+  (pushnew (or buffer (current-buffer)) magit-refresh-needing-buffers :test 'eq))
+
+(defun magit-refresh ()
+  "Refresh current buffer to match repository state.
+Also revert every unmodified buffer visiting files
+in the corresponding directory."
+  (interactive)
+  (magit-with-refresh
+    (magit-need-refresh)))
+
+(defun magit-refresh-all ()
+  "Refresh all magit buffers to match respective repository states.
+Also revert every unmodified buffer visiting files
+in the corresponding directories."
+  (interactive)
+  (magit-for-all-buffers #'magit-refresh-buffer default-directory))
+
+;;; Untracked files
+
+(defun magit-wash-untracked-file ()
+  (if (looking-at "^? \\(.*\\)$")
+      (let ((file (match-string-no-properties 1)))
+        (delete-region (point) (+ (line-end-position) 1))
+        (magit-with-section file 'file
+          (magit-set-section-info file)
+          (insert "\t" file "\n"))
+        t)
+    nil))
+
+(defun magit-wash-untracked-files ()
+  ;; Setting magit-old-top-section to nil speeds up washing: no time
+  ;; is wasted looking up the old visibility, which doesn't matter for
+  ;; untracked files.
+  ;;
+  ;; XXX - speed this up in a more general way.
+  ;;
+  (let ((magit-old-top-section nil))
+    (magit-wash-sequence #'magit-wash-untracked-file)))
+
+(defun magit-insert-untracked-files ()
+  (unless (string= (magit-get "status" "showUntrackedFiles") "no")
+    (apply 'magit-git-section
+           `(untracked
+             "Untracked files:"
+             magit-wash-untracked-files
+             "ls-files" "--others" "-t" "--exclude-standard"
+             ,@(when magit-omit-untracked-dir-contents
+                 '("--directory"))))))
+
+;;; Diffs and Hunks
+
+(defvar magit-diff-context-lines 3)
+
+(defun magit-diff-U-arg ()
+  (format "-U%d" magit-diff-context-lines))
+
+(defun magit-diff-smaller-hunks (&optional count)
+  "Decrease the context for diff hunks by COUNT."
+  (interactive "p")
+  (setq magit-diff-context-lines (max 0 (- magit-diff-context-lines count)))
+  (magit-refresh))
+
+(defun magit-diff-larger-hunks (&optional count)
+  "Increase the context for diff hunks by COUNT."
+  (interactive "p")
+  (setq magit-diff-context-lines (+ magit-diff-context-lines count))
+  (magit-refresh))
+
+(defun magit-diff-default-hunks ()
+  "Reset context for diff hunks to the default size."
+  (interactive "")
+  (setq magit-diff-context-lines 3)
+  (magit-refresh))
+
+(defun magit-toggle-diff-refine-hunk (&optional other)
+  (interactive "P")
+  "Turn diff-hunk refining on or off.
+
+If hunk refining is currently on, then hunk refining is turned off.
+If hunk refining is off, then hunk refining is turned on, in
+`selected' mode (only the currently selected hunk is refined).
+
+With a prefix argument, the \"third choice\" is used instead:
+If hunk refining is currently on, then refining is kept on, but
+the refining mode (`selected' or `all') is switched.
+If hunk refining is off, then hunk refining is turned on, in
+`all' mode (all hunks refined).
+
+Customize `magit-diff-refine-hunk' to change the default mode."
+  (let* ((old magit-diff-refine-hunk)
+         (new
+          (if other
+              (if (eq old 'all) t 'all)
+            (not old))))
+
+    ;; remove any old refining in currently highlighted section
+    (when (and magit-highlighted-section old (not (eq old 'all)))
+      (magit-unrefine-section magit-highlighted-section))
+
+    ;; set variable to new value locally
+    (set (make-local-variable 'magit-diff-refine-hunk) new)
+
+    ;; if now highlighting in "selected only" mode, turn refining back
+    ;; on in the current section
+    (when (and magit-highlighted-section new (not (eq new 'all)))
+      (magit-refine-section magit-highlighted-section))
+
+    ;; `all' mode being turned on or off needs a complete refresh
+    (when (or (eq old 'all) (eq new 'all))
+      (magit-refresh))))
+
+(defun magit-diff-line-file ()
+  (cond ((looking-at "^diff --git ./\\(.*\\) ./\\(.*\\)$")
+         (match-string-no-properties 2))
+        ((looking-at "^diff --cc +\\(.*\\)$")
+         (match-string-no-properties 1))
+        (t
+         nil)))
+
+(defun magit-wash-diffs ()
+  (magit-wash-sequence #'magit-wash-diff-or-other-file))
+
+(defun magit-wash-diff-or-other-file ()
+  (or (magit-wash-diff)
+      (magit-wash-other-file)))
+
+(defun magit-wash-other-file ()
+  (if (looking-at "^? \\(.*\\)$")
+      (let ((file (match-string-no-properties 1)))
+        (delete-region (point) (+ (line-end-position) 1))
+        (magit-with-section file 'file
+          (magit-set-section-info file)
+          (insert "\tNew      " file "\n"))
+        t)
+    nil))
+
+(defvar magit-hide-diffs nil)
+
+(defvar magit-indentation-level 1)
+
+(defun magit-insert-diff-title (status file file2)
+  (let ((status-text (case status
+                       ((unmerged)
+                        (format "Unmerged   %s" file))
+                       ((new)
+                        (format "New        %s" file))
+                       ((deleted)
+                        (format "Deleted    %s" file))
+                       ((renamed)
+                        (format "Renamed    %s   (from %s)"
+                                file file2))
+                       ((modified)
+                        (format "Modified   %s" file))
+                       ((typechange)
+                        (format "Typechange %s" file))
+                       (t
+                        (format "?          %s" file)))))
+    (insert (make-string magit-indentation-level ?\t) status-text "\n")))
+
+(defvar magit-current-diff-range nil
+  "Used internally when setting up magit diff sections.")
+
+(defun magit-wash-typechange-section (file)
+  (magit-set-section-info (list 'typechange file))
+  (let ((first-start (point-marker))
+        (second-start (progn (forward-line 1)
+                             (search-forward-regexp "^diff")
+                             (beginning-of-line)
+                             (point-marker))))
+    (let ((magit-indentation-level (+ magit-indentation-level 1)))
+      (save-restriction
+        (narrow-to-region first-start second-start)
+        (goto-char (point-min))
+        (magit-with-section file 'diff
+          (magit-wash-diff-section)))
+      (save-restriction
+        (narrow-to-region second-start (point-max))
+        (goto-char (point-min))
+        (magit-with-section file 'diff
+          (magit-wash-diff-section))))))
+
+(defun magit-wash-diff-section ()
+  (cond ((looking-at "^\\* Unmerged path \\(.*\\)")
+         (let ((file (match-string-no-properties 1)))
+           (delete-region (point) (line-end-position))
+           (insert "\tUnmerged " file "\n")
+           (magit-set-section-info (list 'unmerged file nil))
+           t))
+        ((looking-at "^diff")
+         (let ((file (magit-diff-line-file))
+               (end (save-excursion
+                      (forward-line) ;; skip over "diff" line
+                      (if (search-forward-regexp "^diff\\|^@@" nil t)
+                          (goto-char (match-beginning 0))
+                        (goto-char (point-max)))
+                      (point-marker))))
+           (let* ((status (cond
+                           ((looking-at "^diff --cc")
+                            'unmerged)
+                           ((save-excursion
+                              (search-forward-regexp "^new file" end t))
+                            'new)
+                           ((save-excursion
+                              (search-forward-regexp "^deleted" end t))
+                            'deleted)
+                           ((save-excursion
+                              (search-forward-regexp "^rename" end t))
+                            'renamed)
+                           (t
+                            'modified)))
+                  (file2 (cond
+                          ((save-excursion
+                             (search-forward-regexp "^rename from \\(.*\\)"
+                                                    end t))
+                           (match-string-no-properties 1)))))
+             (magit-set-section-info (list status
+                                           file
+                                           (or file2 file)
+                                           magit-current-diff-range))
+             (magit-insert-diff-title status file file2)
+             (when (search-forward-regexp "\\(--- \\(.*\\)\n\\+\\+\\+ \\(.*\\)\n\\)" () t)
+               (when (match-string 1)
+                 (add-text-properties (match-beginning 1) (match-end 1)
+                                      '(face magit-diff-hunk-header))
+                 (add-text-properties (match-beginning 2) (match-end 2)
+                                      '(face magit-diff-file-header))
+                 (add-text-properties (match-beginning 3) (match-end 3)
+                                      '(face magit-diff-file-header))))
+             (goto-char end)
+             (let ((magit-section-hidden-default nil))
+               (magit-wash-sequence #'magit-wash-hunk))))
+         t)
+        (t
+         nil)))
+
+(defun magit-wash-diff ()
+  (let ((magit-section-hidden-default magit-hide-diffs))
+    (magit-with-section (magit-current-line) 'diff
+      (magit-wash-diff-section))))
+
+(defun magit-diff-item-kind (diff)
+  (car (magit-section-info diff)))
+
+(defun magit-diff-item-file (diff)
+  (cadr (magit-section-info diff)))
+
+(defun magit-diff-item-file2 (diff)
+  (caddr (magit-section-info diff)))
+
+(defun magit-diff-item-range (diff)
+  (nth 3 (magit-section-info diff)))
+
+(defun magit-wash-hunk ()
+  (cond ((looking-at "\\(^@+\\)[^@]*@+.*")
+         (let ((n-columns (1- (length (match-string 1))))
+               (head (match-string 0))
+               (hunk-start-pos (point)))
+           (magit-with-section head 'hunk
+             (add-text-properties (match-beginning 0) (match-end 0)
+                                  '(face magit-diff-hunk-header))
+             (forward-line)
+             (while (not (or (eobp)
+                             (looking-at "^diff\\|^@@")))
+               (magit-highlight-line-whitespace)
+               (let ((prefix (buffer-substring-no-properties
+                              (point) (min (+ (point) n-columns) (point-max)))))
+                 (cond ((string-match "\\+" prefix)
+                        (magit-put-line-property 'face 'magit-diff-add))
+                       ((string-match "-" prefix)
+                        (magit-put-line-property 'face 'magit-diff-del))
+                       (t
+                        (magit-put-line-property 'face 'magit-diff-none))))
+               (forward-line)))
+
+           (when (eq magit-diff-refine-hunk 'all)
+             (save-excursion
+               (goto-char hunk-start-pos)
+               (diff-refine-hunk))))
+         t)
+        (t
+         nil)))
+
+(defvar magit-diff-options nil)
+
+(defun magit-insert-diff (file status)
+  (let ((cmd magit-git-executable)
+        (args (append (list "diff")
+                      (list (magit-diff-U-arg))
+                      magit-diff-options
+                      (list "--" file))))
+    (let ((p (point)))
+      (magit-git-insert args)
+      (if (not (eq (char-before) ?\n))
+          (insert "\n"))
+      (save-restriction
+        (narrow-to-region p (point))
+        (goto-char p)
+        (cond
+         ((eq status 'typechange)
+          (magit-insert-diff-title status file file)
+          (magit-wash-typechange-section file))
+         (t
+          (magit-wash-diff-section)))
+        (goto-char (point-max))))))
+
+(defvar magit-last-raw-diff nil)
+(defvar magit-ignore-unmerged-raw-diffs nil)
+
+(defun magit-wash-raw-diffs ()
+  (let ((magit-last-raw-diff nil))
+    (magit-wash-sequence #'magit-wash-raw-diff)))
+
+(defun magit-wash-raw-diff ()
+  (if (looking-at
+       ":\\([0-7]+\\) \\([0-7]+\\) [0-9a-f]+ [0-9a-f]+ \\(.\\)[0-9]*\t\\([^\t\n]+\\)$")
+      (let ((old-perm (match-string-no-properties 1))
+            (new-perm (match-string-no-properties 2))
+            (status (case (string-to-char (match-string-no-properties 3))
+                      (?A 'new)
+                      (?D 'deleted)
+                      (?M 'modified)
+                      (?U 'unmerged)
+                      (?T 'typechange)
+                      (t     nil)))
+            (file (match-string-no-properties 4)))
+        ;; If this is for the same file as the last diff, ignore it.
+        ;; Unmerged files seem to get two entries.
+        ;; We also ignore unmerged files when told so.
+        (if (or (equal file magit-last-raw-diff)
+                (and magit-ignore-unmerged-raw-diffs (eq status 'unmerged)))
+            (delete-region (point) (+ (line-end-position) 1))
+          (setq magit-last-raw-diff file)
+          ;; The 'diff' section that is created here will not work with
+          ;; magit-insert-diff-item-patch etc when we leave it empty.
+          ;; Luckily, raw diffs are only produced for staged and
+          ;; unstaged changes, and we never call
+          ;; magit-insert-diff-item-patch on them.  This is a bit
+          ;; brittle, of course.
+          (let ((magit-section-hidden-default magit-hide-diffs))
+            (magit-with-section file 'diff
+              (delete-region (point) (+ (line-end-position) 1))
+              (if (not (magit-section-hidden magit-top-section))
+                  (magit-insert-diff file status)
+                (magit-set-section-info (list status file nil))
+                (magit-set-section-needs-refresh-on-show t)
+                (magit-insert-diff-title status file nil)))))
+        t)
+    nil))
+
+(defun magit-hunk-item-diff (hunk)
+  (let ((diff (magit-section-parent hunk)))
+    (or (eq (magit-section-type diff) 'diff)
+        (error "Huh?  Parent of hunk not a diff"))
+    diff))
+
+(defun magit-diff-item-insert-header (diff buf)
+  (let ((beg (save-excursion
+               (goto-char (magit-section-beginning diff))
+               (forward-line)
+               (point)))
+        (end (if (magit-section-children diff)
+                 (magit-section-beginning (car (magit-section-children diff)))
+               (magit-section-end diff))))
+    (magit-insert-region beg end buf)))
+
+(defun magit-insert-diff-item-patch (diff buf)
+  (let ((beg (save-excursion
+               (goto-char (magit-section-beginning diff))
+               (forward-line)
+               (point)))
+        (end (magit-section-end diff)))
+    (magit-insert-region beg end buf)))
+
+(defun magit-insert-hunk-item-patch (hunk buf)
+  (magit-diff-item-insert-header (magit-hunk-item-diff hunk) buf)
+  (magit-insert-region (magit-section-beginning hunk) (magit-section-end hunk)
+                       buf))
+
+(defun magit-insert-hunk-item-region-patch (hunk reverse beg end buf)
+  (magit-diff-item-insert-header (magit-hunk-item-diff hunk) buf)
+  (save-excursion
+    (goto-char (magit-section-beginning hunk))
+    (magit-insert-current-line buf)
+    (forward-line)
+    (let ((copy-op (if reverse "+" "-")))
+      (while (< (point) (magit-section-end hunk))
+        (if (and (<= beg (point)) (< (point) end))
+            (magit-insert-current-line buf)
+          (cond ((looking-at " ")
+                 (magit-insert-current-line buf))
+                ((looking-at copy-op)
+                 (let ((text (buffer-substring-no-properties
+                              (+ (point) 1) (line-beginning-position 2))))
+                   (with-current-buffer buf
+                     (insert " " text))))))
+        (forward-line))))
+  (with-current-buffer buf
+    (diff-fixup-modifs (point-min) (point-max))))
+
+(defun magit-hunk-item-is-conflict-p (hunk)
+  ;;; XXX - Using the title is a bit too clever...
+  (string-match "^diff --cc"
+                (magit-section-title (magit-hunk-item-diff hunk))))
+
+(defun magit-hunk-item-target-line (hunk)
+  (save-excursion
+    (beginning-of-line)
+    (let ((line (line-number-at-pos)))
+      (goto-char (magit-section-beginning hunk))
+      (if (not (looking-at "@@+ .* \\+\\([0-9]+\\)\\(,[0-9]+\\)? @@+"))
+          (error "Hunk header not found"))
+      (let ((target (string-to-number (match-string 1))))
+        (forward-line)
+        (while (< (line-number-at-pos) line)
+          ;; XXX - deal with combined diffs
+          (if (not (looking-at "-"))
+              (setq target (+ target 1)))
+          (forward-line))
+        target))))
+
+(defun magit-show (commit filename &optional select prefix)
+  "Returns a buffer containing the contents of the file FILENAME, as stored in
+COMMIT.  COMMIT may be one of the following:
+
+- A string with the name of a commit, such as \"head\" or \"dae86e\".  See 'git
+  help revisions' for syntax.
+- The symbol 'index, indicating that you want the version in Git's index or
+  staging area.
+- The symbol 'working, indicating that you want the version in the working
+  directory.  In this case you'll get a buffer visiting the file.  If there's
+  already a buffer visiting that file, you'll get that one.
+
+When called interactively or when SELECT is non-nil, make the buffer active,
+either in another window or (with a prefix argument) in the current window."
+  (interactive (let* ((revision (magit-read-rev "Retrieve file from revision"))
+                      (filename (magit-read-file-from-rev revision)))
+                 (list revision filename t current-prefix-arg)))
+  (if (eq commit 'working)
+      (find-file-noselect filename)
+    (let ((buffer (create-file-buffer (format "%s.%s" filename (replace-regexp-in-string ".*/" "" (prin1-to-string commit t))))))
+      (cond
+       ((eq commit 'index)
+        (let ((checkout-string (magit-git-string "checkout-index"
+                                                 "--temp"
+                                                 filename)))
+          (string-match "^\\(.*\\)\t" checkout-string)
+          (with-current-buffer buffer
+            (let ((tmpname (match-string 1 checkout-string)))
+              (magit-with-silent-modifications
+               (insert-file-contents tmpname nil nil nil t))
+              (delete-file tmpname)))))
+       (t
+        (with-current-buffer buffer
+          (magit-with-silent-modifications
+           (magit-git-insert (list "cat-file" "-p"
+                                   (concat commit ":" filename)))))))
+      (with-current-buffer buffer
+        (let ((buffer-file-name filename))
+          (normal-mode))
+        (goto-char (point-min)))
+      (if select
+          (if prefix
+              (switch-to-buffer buffer)
+            (switch-to-buffer-other-window buffer))
+        buffer))))
+
+(defmacro with-magit-tmp-buffer (var &rest body)
+  (declare (indent 1)
+           (debug (symbolp &rest form)))
+  `(let ((,var (generate-new-buffer magit-tmp-buffer-name)))
+     (unwind-protect
+         (progn ,@body)
+       (kill-buffer ,var))))
+
+(defun magit-apply-diff-item (diff &rest args)
+  (when (zerop magit-diff-context-lines)
+    (setq args (cons "--unidiff-zero" args)))
+  (with-magit-tmp-buffer tmp
+    (magit-insert-diff-item-patch diff tmp)
+    (apply #'magit-run-git-with-input tmp
+           "apply" (append args (list "-")))))
+
+(defun magit-apply-hunk-item* (hunk reverse &rest args)
+  "Apply single hunk or part of a hunk to the index or working file.
+
+This function is the core of magit's stage, unstage, apply, and
+revert operations.  HUNK (or the portion of it selected by the
+region) will be applied to either the index, if \"--cached\" is a
+member of ARGS, or to the working file otherwise."
+  (let ((zero-context (zerop magit-diff-context-lines))
+        (use-region (magit-use-region-p)))
+    (when zero-context
+      (setq args (cons "--unidiff-zero" args)))
+    (when reverse
+      (setq args (cons "--reverse" args)))
+    (when (and use-region zero-context)
+      (error (concat "Not enough context to partially apply hunk.  "
+                     "Use `+' to increase context.")))
+    (with-magit-tmp-buffer tmp
+      (if use-region
+          (magit-insert-hunk-item-region-patch
+           hunk reverse (region-beginning) (region-end) tmp)
+        (magit-insert-hunk-item-patch hunk tmp))
+      (apply #'magit-run-git-with-input tmp
+             "apply" (append args (list "-"))))))
+
+(defun magit-apply-hunk-item (hunk &rest args)
+  (apply #'magit-apply-hunk-item* hunk nil args))
+
+(defun magit-apply-hunk-item-reverse (hunk &rest args)
+  (apply #'magit-apply-hunk-item* hunk t args))
+
+(magit-define-inserter unstaged-changes (title)
+  (let ((magit-hide-diffs t)
+        (magit-current-diff-range (cons 'index 'working)))
+    (let ((magit-diff-options (append '() magit-diff-options)))
+      (magit-git-section 'unstaged title 'magit-wash-raw-diffs
+                         "diff-files"))))
+
+(magit-define-inserter staged-changes (staged no-commit)
+  (let ((magit-current-diff-range (cons "HEAD" 'index)))
+    (when staged
+      (let ((magit-hide-diffs t)
+            (base (if no-commit
+                      (magit-git-string "mktree")
+                    "HEAD")))
+        (let ((magit-diff-options (append '("--cached") magit-diff-options))
+              (magit-ignore-unmerged-raw-diffs t))
+          (magit-git-section 'staged "Staged changes:" 'magit-wash-raw-diffs
+                             "diff-index" "--cached"
+                             base))))))
+
+;;; Logs and Commits
+
+                                        ; Note: making this a plain defcustom would probably let users break
+                                        ; the parser too easily
+(defvar magit-git-log-options
+  (list
+   "--pretty=format:* %h %s"
+   (format "--abbrev=%s" magit-sha1-abbrev-length)))
+                                        ; --decorate=full otherwise some ref prefixes are stripped
+                                        ;  '("--pretty=format:* %H%d %s" "--decorate=full"))
+
+;;
+;; Regexps for parsing ref names
+;;
+;; see the `git-check-ref-format' manpage for details
+
+(defconst magit-ref-nonchars "\000-\037\177 ~^:?*[\\"
+  "Characters specifically disallowed from appearing in Git symbolic refs.
+
+Evaluate (man \"git-check-ref-format\") for details")
+
+(defconst magit-ref-nonslash-re
+  (concat "\\(?:"
+          ;; "no slash-separated component can begin with a dot ." (rule 1)
+          "[^" magit-ref-nonchars "./]"
+          ;; "cannot have two consecutive dots ..  anywhere." (rule 3)
+          "\\.?"
+          "\\)*")
+  "Regexp that matches the non-slash parts of a ref name.
+
+Evaluate (man \"git-check-ref-format\") for details")
+
+(defconst magit-refname-re
+  (concat
+   "\\(?:HEAD\\|"
+
+   "\\(?:tag: \\)?"
+
+   ;; optional non-slash sequence at the beginning
+   magit-ref-nonslash-re
+
+   ;; any number of slash-prefixed sequences
+   "\\(?:"
+   "/"
+   magit-ref-nonslash-re
+   "\\)*"
+
+   "/" ;; "must contain at least one /." (rule 2)
+   magit-ref-nonslash-re
+
+   ;; "cannot end with a slash / nor a dot .." (rule 5)
+   "[^" magit-ref-nonchars "./]"
+
+   "\\)"
+   )
+  "Regexp that matches a git symbolic reference name.
+
+Evaluate (man \"git-check-ref-format\") for details")
+
+(defconst magit-log-oneline-re
+  (concat
+   "^\\([_\\*|/ -.]+\\)?"                          ; graph   (1)
+   "\\(?:"
+   "\\([0-9a-fA-F]+\\)"                            ; sha1    (2)
+   "\\(?:"                                         ; refs    (3)
+   " "
+   "\\("
+   "("
+   magit-refname-re "\\(?:, " magit-refname-re "\\)*"
+   ")"
+   "\\)"
+   "\\)?"
+   "\\)?"
+   " ?\\(.*\\)$"                                   ; msg     (4)
+   ))
+
+(defconst magit-log-longline-re
+  (concat
+   ;; use \0 delimiter (from -z option) to identify commits. this prevents
+   ;; commit messages containing lines like "commit 00000" from polluting the
+   ;; display
+   "\\(?:\\(?:\\`\\|\0\\)"
+   "\\([_\\*|/ -.]+\\)?"                           ; graph   (1)
+   "commit "
+   "\\([0-9a-fA-F]+\\)"                            ; sha1    (2)
+   "\\(?:"                                         ; refs    (3)
+   " "
+   "\\("
+   "("
+   magit-refname-re "\\(?:, " magit-refname-re "\\)*"
+   ")"
+   "\\)"
+   "\\)?"
+   "$\\)?"
+   " ?\\(.*\\)$"                                   ; msg     (4)
+   ))
+
+(defvar magit-present-log-line-function 'magit-present-log-line
+  "The function to use when generating a log line.
+It takes four args: CHART, SHA1, REFS and MESSAGE.  The function
+must return a string which will represent the log line.")
+
+(defun magit-log-get-bisect-state-color (suffix)
+  (if (string= suffix "bad")
+      (list suffix 'magit-log-head-label-bisect-bad)
+    (list suffix 'magit-log-head-label-bisect-good)))
+
+(defun magit-log-get-patches-color (suffix)
+  (list (and (string-match ".+/\\(.+\\)" suffix)
+             (match-string 1 suffix))
+        'magit-log-head-label-patches))
+
+(defvar magit-log-remotes-color-hook nil)
+
+(defun magit-log-get-remotes-color (suffix)
+  (or
+   (run-hook-with-args-until-success
+    'magit-log-remotes-color-hook suffix)
+   (list suffix 'magit-log-head-label-remote)))
+
+(defvar magit-refs-namespaces
+  '(("tags" . magit-log-head-label-tags)
+    ("remotes" magit-log-get-remotes-color)
+    ("heads" . magit-log-head-label-local)
+    ("patches" magit-log-get-patches-color)
+    ("bisect" magit-log-get-bisect-state-color)))
+
+(defun magit-ref-get-label-color (r)
+  (let ((uninteresting (loop for re in magit-uninteresting-refs
+                             thereis (string-match re r))))
+    (if uninteresting (list nil nil)
+      (let* ((ref-re "\\(?:tag: \\)?refs/\\(?:\\([^/]+\\)/\\)?\\(.+\\)")
+             (label (and (string-match ref-re r)
+                         (match-string 2 r)))
+             (res (let ((colorizer
+                         (cdr (assoc (match-string 1 r)
+                                     magit-refs-namespaces))))
+                    (cond ((null colorizer)
+                           (list r 'magit-log-head-label-default))
+                          ((symbolp colorizer)
+                           (list label colorizer))
+                          ((listp colorizer)
+                           (funcall (car colorizer)
+                                    (match-string 2 r)))
+                          (t
+                           (list r 'magit-log-head-label-default))))))
+        res))))
+
+(defun magit-present-log-line (graph sha1 refs message)
+  "The default log line generator."
+  (let ((string-refs
+         (when refs
+           (let ((colored-labels
+                  (delete nil
+                          (mapcar (lambda (r)
+                                    (destructuring-bind (label face)
+                                        (magit-ref-get-label-color r)
+                                      (and label
+                                           (propertize label 'face face))))
+                                  refs))))
+             (concat
+              (mapconcat 'identity colored-labels " ")
+              " ")))))
+
+    (concat
+     (if sha1
+         (propertize sha1 'face 'magit-log-sha1)
+       (insert-char ? magit-sha1-abbrev-length))
+     " "
+     (when graph
+       (propertize graph 'face 'magit-log-graph))
+     string-refs
+     (when message
+       (propertize message 'face 'magit-log-message)))))
+
+(defvar magit-log-count ()
+  "Internal var used to count the number of logs actually added in a buffer.")
+
+(defmacro magit-create-log-buffer-sections (&rest body)
+  "Empty current buffer of text and magit's section, and then evaluate BODY.
+
+if the number of logs inserted in the buffer is `magit-log-cutoff-length'
+insert a line to tell how to insert more of them"
+  (declare (indent 0))
+  `(let ((magit-log-count 0) (inhibit-read-only t))
+     (magit-create-buffer-sections
+       (magit-with-section 'log nil
+         ,@body
+         (if (= magit-log-count magit-log-cutoff-length)
+             (magit-with-section "longer"  'longer
+               (insert "type \"e\" to show more logs\n")))))))
+
+(defun magit-wash-log-line (style)
+  (beginning-of-line)
+  (let ((line-re (cond ((eq style 'long) magit-log-longline-re)
+                       (t magit-log-oneline-re))))
+    (cond
+     ((looking-at line-re)
+      (let ((chart (match-string 1))
+            (sha1 (match-string 2))
+            (msg (match-string 4))
+            (refs (when (match-string 3)
+                    (delq nil
+                          (mapcar
+                           (lambda (s)
+                             (and (not
+                                   (or (string= s "tag:")
+                                       (string= s "HEAD"))) ; as of 1.6.6
+                                  s))
+                           (split-string (match-string 3) "[(), ]" t))))))
+        (delete-region (point-at-bol) (point-at-eol))
+        (insert (funcall magit-present-log-line-function chart sha1 refs msg))
+        (goto-char (point-at-bol))
+        (if sha1
+            (magit-with-section sha1 'commit
+              (when magit-log-count (setq magit-log-count (1+ magit-log-count)))
+              (magit-set-section-info sha1)
+              (forward-line))
+          (forward-line))))
+     (t
+      (forward-line)))
+    t))
+
+(defun magit-wash-log (&optional style)
+  (let ((magit-old-top-section nil))
+    (magit-wash-sequence (apply-partially 'magit-wash-log-line style))))
+
+(defvar magit-currently-shown-commit nil)
+
+(defun magit-wash-commit ()
+  (let ((magit-current-diff-range))
+    (when (looking-at "^commit \\([0-9a-fA-F]\\{40\\}\\)")
+      (setq magit-current-diff-range (match-string 1))
+      (add-text-properties (match-beginning 1) (match-end 1)
+                           '(face magit-log-sha1)))
+    (cond
+     ((search-forward-regexp "^Merge: \\([0-9a-fA-F]+\\) \\([0-9a-fA-F]+\\)$" nil t)
+      (setq magit-current-diff-range (cons (cons (match-string 1)
+                                                 (match-string 2))
+                                           magit-current-diff-range))
+      (let ((first (magit-set-section nil 'commit (match-beginning 1) (match-end 1)))
+            (second (magit-set-section nil 'commit (match-beginning 2) (match-end 2))))
+        (magit-set-section-info (match-string 1) first)
+        (magit-set-section-info (match-string 2) second))
+      (make-commit-button (match-beginning 1) (match-end 1))
+      (make-commit-button (match-beginning 2) (match-end 2)))
+     (t
+      (setq magit-current-diff-range (cons (concat magit-current-diff-range "^")
+                                           magit-current-diff-range))))
+    (search-forward-regexp "^$")
+    (while (and
+            (search-forward-regexp "\\(\\b[0-9a-fA-F]\\{4,40\\}\\b\\)\\|\\(^diff\\)" nil 'noerror)
+            (not (match-string 2)))
+      (let ((sha1 (match-string 1))
+            (start (match-beginning 1))
+            (end (match-end 1)))
+        (when (string-equal "commit" (magit-git-string "cat-file" "-t" sha1))
+          (make-commit-button start end)
+          (let ((section (magit-set-section sha1 'commit start end)))
+            (magit-set-section-info sha1 section)))))
+    (beginning-of-line)
+    (when (looking-at "^diff")
+      (magit-wash-diffs))
+    (goto-char (point-max))
+    (insert "\n")
+    (if magit-back-navigation-history
+        (magit-with-section "[back]" 'button
+          (insert-text-button "[back]"
+                              'help-echo "Previous commit"
+                              'action 'magit-show-commit-backward
+                              'follow-link t
+                              'mouse-face 'magit-item-highlight)))
+    (insert " ")
+    (if magit-forward-navigation-history
+        (magit-with-section "[forward]" 'button
+          (insert-text-button "[forward]"
+                              'help-echo "Next commit"
+                              'action 'magit-show-commit-forward
+                              'follow-link t
+                              'mouse-face 'magit-item-highlight)))))
+
+(defun make-commit-button (start end)
+  (make-text-button start end
+                    'help-echo "Visit commit"
+                    'action (lambda (button)
+                              (save-excursion
+                                (goto-char button)
+                                (magit-visit-item)))
+                    'follow-link t
+                    'mouse-face 'magit-item-highlight
+                    'face 'magit-log-sha1))
+
+(defun magit-refresh-commit-buffer (commit)
+  (magit-configure-have-abbrev)
+  (magit-configure-have-decorate)
+  (magit-create-buffer-sections
+    (apply #'magit-git-section nil nil
+           'magit-wash-commit
+           "log"
+           "--max-count=1"
+           "--pretty=medium"
+           `(,@(if magit-have-abbrev (list "--no-abbrev-commit"))
+             ,@(if magit-have-decorate (list "--decorate=full"))
+             "--cc"
+             "-p" ,commit))))
+
+(define-derived-mode magit-commit-mode magit-mode "Magit"
+  "Mode to view a git commit.
+
+\\{magit-commit-mode-map}"
+  :group 'magit)
+
+(defvar magit-commit-buffer-name "*magit-commit*"
+  "Buffer name for displaying commit log messages.")
+
+(defun magit-show-commit (commit &optional scroll inhibit-history select)
+  "Show information about a commit in the buffer named by
+`magit-commit-buffer-name'.  COMMIT can be any valid name for a commit
+in the current Git repository.
+
+When called interactively or when SELECT is non-nil, switch to
+the commit buffer using `pop-to-buffer'.
+
+Unless INHIBIT-HISTORY is non-nil, the commit currently shown
+will be pushed onto `magit-back-navigation-history' and
+`magit-forward-navigation-history' will be cleared.
+
+Noninteractively, if the commit is already displayed and SCROLL
+is provided, call SCROLL's function definition in the commit
+window.  (`scroll-up' and `scroll-down' are typically passed in
+for this argument.)"
+  (interactive (list (magit-read-rev "Show commit (hash or ref)")
+                     nil nil t))
+  (when (magit-section-p commit)
+    (setq commit (magit-section-info commit)))
+  (unless (eql 0 (magit-git-exit-code "cat-file" "commit" commit))
+    (error "%s is not a commit" commit))
+  (let ((dir default-directory)
+        (buf (get-buffer-create magit-commit-buffer-name)))
+    (cond
+     ((and (equal magit-currently-shown-commit commit)
+           ;; if it's empty then the buffer was killed
+           (with-current-buffer buf
+             (> (length (buffer-string)) 1)))
+      (let ((win (get-buffer-window buf)))
+        (cond ((not win)
+               (display-buffer buf))
+              (scroll
+               (with-selected-window win
+                 (funcall scroll))))))
+     (commit
+      (display-buffer buf)
+      (with-current-buffer buf
+        (unless inhibit-history
+          (push (cons default-directory magit-currently-shown-commit)
+                magit-back-navigation-history)
+          (setq magit-forward-navigation-history nil))
+        (setq magit-currently-shown-commit commit)
+        (goto-char (point-min))
+        (magit-mode-init dir 'magit-commit-mode
+                         #'magit-refresh-commit-buffer commit))))
+    (if select
+        (pop-to-buffer buf))))
+
+(defun magit-show-commit-backward (&optional ignored)
+  ;; Ignore argument passed by push-button
+  "Show the commit at the head of `magit-back-navigation-history in
+`magit-commit-buffer-name`."
+  (interactive)
+  (with-current-buffer magit-commit-buffer-name
+    (unless magit-back-navigation-history
+      (error "No previous commit."))
+    (let ((histitem (pop magit-back-navigation-history)))
+      (push (cons default-directory magit-currently-shown-commit)
+            magit-forward-navigation-history)
+      (setq default-directory (car histitem))
+      (magit-show-commit (cdr histitem) nil 'inhibit-history))))
+
+(defun magit-show-commit-forward (&optional ignored)
+  ;; Ignore argument passed by push-button
+  "Show the commit at the head of `magit-forward-navigation-history in
+`magit-commit-buffer-name`."
+  (interactive)
+  (with-current-buffer magit-commit-buffer-name
+    (unless magit-forward-navigation-history
+      (error "No next commit."))
+    (let ((histitem (pop magit-forward-navigation-history)))
+      (push (cons default-directory magit-currently-shown-commit)
+            magit-back-navigation-history)
+      (setq default-directory (car histitem))
+      (magit-show-commit (cdr histitem) nil 'inhibit-history))))
+
+(defvar magit-marked-commit nil)
+
+(defvar magit-mark-overlay nil)
+(make-variable-buffer-local 'magit-mark-overlay)
+(put 'magit-mark-overlay 'permanent-local t)
+
+(defun magit-refresh-marked-commits ()
+  (magit-for-all-buffers #'magit-refresh-marked-commits-in-buffer))
+
+(defun magit-refresh-marked-commits-in-buffer ()
+  (if (not magit-mark-overlay)
+      (let ((ov (make-overlay 1 1)))
+        (overlay-put ov 'face 'magit-item-mark)
+        (setq magit-mark-overlay ov)))
+  (delete-overlay magit-mark-overlay)
+  (magit-for-all-sections
+   (lambda (section)
+     (when (and (eq (magit-section-type section) 'commit)
+                (equal (magit-section-info section)
+                       magit-marked-commit))
+       (move-overlay magit-mark-overlay
+                     (magit-section-beginning section)
+                     (magit-section-end section)
+                     (current-buffer))))))
+
+(defun magit-set-marked-commit (commit)
+  (setq magit-marked-commit commit)
+  (magit-refresh-marked-commits))
+
+(defun magit-marked-commit ()
+  (or magit-marked-commit
+      (error "No commit marked")))
+
+(defun magit-remote-branch-name (remote branch)
+  "Get the name of the branch BRANCH on remote REMOTE"
+  (if (string= remote ".")
+      branch
+    (concat remote "/" branch)))
+
+(magit-define-inserter unpulled-commits (remote branch)
+  (when remote
+    (apply #'magit-git-section
+           'unpulled "Unpulled commits:" 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    (format "HEAD..%s" (magit-remote-branch-name remote branch)))))))
+
+(magit-define-inserter unpushed-commits (remote branch)
+  (when remote
+    (apply #'magit-git-section
+           'unpushed "Unpushed commits:" 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    (format "%s..HEAD" (magit-remote-branch-name remote branch)))))))
+
+(defun magit-remote-branch-for (local-branch &optional fully-qualified-name)
+  "Guess the remote branch name that LOCAL-BRANCH is tracking.
+Gives a fully qualified name (e.g., refs/remotes/origin/master) if
+FULLY-QUALIFIED-NAME is non-nil."
+  (let ((merge (magit-get "branch" local-branch "merge")))
+    (save-match-data
+      (if (and merge (string-match "^refs/heads/\\(.+\\)" merge))
+          (concat (if fully-qualified-name
+                      (let ((remote-name (magit-get "branch" local-branch "remote")))
+                        (if (string= "." remote-name)
+                            "refs/heads/"
+                          (concat "refs/remotes/" remote-name "/"))))
+                  (match-string 1 merge))))))
+
+;;; Status
+
+(defvar magit-remote-string-hook nil)
+
+(defun magit-remote-string (remote remote-branch remote-rebase)
+  (cond
+   ((string= "." remote)
+    (concat
+     (when remote-rebase "onto ")
+     "branch "
+     (propertize remote-branch 'face 'magit-branch)))
+   (remote
+    (concat
+     (when remote-rebase "onto ")
+     (propertize remote-branch 'face 'magit-branch)
+     " @ "
+     remote
+     " ("
+     (magit-get "remote" remote "url")
+     ")"))
+   (t
+    (run-hook-with-args-until-success 'magit-remote-string-hook))))
+
+(declare-function magit--bisect-info-for-status "magit-bisect" (branch))
+
+(defun magit-refresh-status ()
+  (magit-create-buffer-sections
+    (magit-with-section 'status nil
+      (let* ((branch (magit-get-current-branch))
+             (remote (and branch (magit-get "branch" branch "remote")))
+             (remote-rebase (and branch (magit-get-boolean "branch" branch "rebase")))
+             (remote-branch (or (and branch (magit-remote-branch-for branch)) branch))
+             (remote-string (magit-remote-string remote remote-branch remote-rebase))
+             (head (magit-git-string
+                    "log"
+                    "--max-count=1"
+                    "--abbrev-commit"
+                    (format "--abbrev=%s" magit-sha1-abbrev-length)
+                    "--pretty=oneline"))
+             (no-commit (not head)))
+        (when remote-string
+          (insert "Remote:   " remote-string "\n"))
+        (insert (format "Local:    %s %s\n"
+                        (propertize (magit--bisect-info-for-status branch)
+                                    'face 'magit-branch)
+                        (abbreviate-file-name default-directory)))
+        (insert (format "Head:     %s\n"
+                        (if no-commit "nothing commited (yet)" head)))
+        (let ((merge-heads (magit-file-lines (concat (magit-git-dir)
+                                                     "MERGE_HEAD"))))
+          (if merge-heads
+              (insert (format "Merging:   %s\n"
+                              (mapconcat 'identity
+                                         (mapcar 'magit-name-rev merge-heads)
+                                         ", ")))))
+        (let ((rebase (magit-rebase-info)))
+          (if rebase
+              (insert (apply 'format "Rebasing: onto %s (%s of %s); Press \"R\" to Abort, Skip, or Continue\n" rebase))))
+        (insert "\n")
+        (magit-git-exit-code "update-index" "--refresh")
+        (magit-insert-stashes)
+        (magit-insert-untracked-files)
+        (magit-insert-pending-changes)
+        (magit-insert-pending-commits)
+        (magit-insert-unpulled-commits remote remote-branch)
+        (let ((staged (or no-commit (magit-anything-staged-p))))
+          (magit-insert-unstaged-changes
+           (if staged "Unstaged changes:" "Changes:"))
+          (magit-insert-staged-changes staged no-commit))
+        (magit-insert-unpushed-commits remote remote-branch)
+        (run-hooks 'magit-refresh-status-hook)))))
+
+(defun magit-init (dir)
+  "Initialize git repository in the DIR directory."
+  (interactive (list (read-directory-name "Directory for Git repository: ")))
+  (let* ((dir (file-name-as-directory (expand-file-name dir)))
+         (topdir (magit-get-top-dir dir)))
+    (when (or (not topdir)
+              (yes-or-no-p
+               (format
+                (if (string-equal topdir dir)
+                    "There is already a Git repository in %s. Reinitialize? "
+                  "There is a Git repository in %s. Create another in %s? ")
+                topdir dir)))
+      (unless (file-directory-p dir)
+        (and (y-or-n-p (format "Directory %s does not exists.  Create it? " dir))
+             (make-directory dir)))
+      (let ((default-directory dir))
+        (magit-run* (list magit-git-executable "init"))))))
+
+(define-derived-mode magit-status-mode magit-mode "Magit"
+  "Mode for looking at git status.
+
+\\{magit-status-mode-map}"
+  :group 'magit)
+
+(defvar magit-default-directory nil)
+
+(defun magit-save-some-buffers (&optional msg pred)
+  "Save some buffers if variable `magit-save-some-buffers' is non-nil.
+If variable `magit-save-some-buffers' is set to 'dontask then
+don't ask the user before saving the buffers, just go ahead and
+do it.
+
+Optional argument MSG is displayed in the minibuffer if variable
+`magit-save-some-buffers' is nil.
+
+Optional second argument PRED determines which buffers are considered:
+If PRED is nil, all the file-visiting buffers are considered.
+If PRED is t, then certain non-file buffers will also be considered.
+If PRED is a zero-argument function, it indicates for each buffer whether
+to consider it or not when called with that buffer current."
+  (interactive)
+  (let ((predicate-function (or pred magit-save-some-buffers-predicate))
+        (magit-default-directory default-directory))
+    (if magit-save-some-buffers
+        (save-some-buffers
+         (eq magit-save-some-buffers 'dontask)
+         predicate-function)
+      (when msg
+        (message msg)))))
+
+(defun magit-save-buffers-predicate-all ()
+  "Prompt to save all buffers with unsaved changes"
+  t)
+
+(defun magit-save-buffers-predicate-tree-only ()
+  "Only prompt to save buffers which are within the current git project (as
+  determined by the dir passed to `magit-status'."
+  (and buffer-file-name
+       (string= (magit-get-top-dir magit-default-directory)
+                (magit-get-top-dir (file-name-directory buffer-file-name)))))
+
+;;;###autoload
+(defun magit-status (dir)
+  "Open a Magit status buffer for the Git repository containing
+DIR.  If DIR is not within a Git repository, offer to create a
+Git repository in DIR.
+
+Interactively, a prefix argument means to ask the user which Git
+repository to use even if `default-directory' is under Git control.
+Two prefix arguments means to ignore `magit-repo-dirs' when asking for
+user input."
+  (interactive (list (if current-prefix-arg
+                         (magit-read-top-dir
+                          (> (prefix-numeric-value current-prefix-arg)
+                             4))
+                       (or (magit-get-top-dir default-directory)
+                           (magit-read-top-dir nil)))))
+  (magit-save-some-buffers)
+  (let ((topdir (magit-get-top-dir dir)))
+    (unless topdir
+      (when (y-or-n-p (format "There is no Git repository in %S.  Create one? "
+                              dir))
+        (magit-init dir)
+        (setq topdir (magit-get-top-dir dir))))
+    (when topdir
+      (let ((buf (or (magit-find-status-buffer topdir)
+                     (generate-new-buffer
+                      (concat "*magit: "
+                              (file-name-nondirectory
+                               (directory-file-name topdir)) "*")))))
+        (funcall magit-status-buffer-switch-function buf)
+        (magit-mode-init topdir 'magit-status-mode #'magit-refresh-status)))))
+
+(magit-define-command automatic-merge (revision)
+  "Merge REVISION into the current 'HEAD'; commit unless merge fails.
+\('git merge REVISION')."
+  (interactive (list (magit-read-rev "Merge" (magit-guess-branch))))
+  (if revision
+      (magit-run-git "merge" (magit-rev-to-git revision))))
+
+(magit-define-command manual-merge (revision)
+  "Merge REVISION into the current 'HEAD'; commit unless merge fails.
+\('git merge REVISION')."
+  (interactive (list (magit-read-rev "Merge" (magit-guess-branch))))
+  (when revision
+    (apply 'magit-run-git
+           "merge" "--no-commit"
+           (magit-rev-to-git revision)
+           magit-custom-options)
+    (when (file-exists-p ".git/MERGE_MSG")
+        (magit-log-edit))))
+
+;;; Staging and Unstaging
+
+(defun magit-stage-item (&optional ask)
+  "Add the item at point to the staging area.
+If ASK is set, ask for the file name rather than picking the one
+at point."
+  (interactive "P")
+  (if ask
+      (magit-run-git "add" (read-file-name "File to stage: "))
+    (magit-section-action (item info "stage")
+      ((untracked file)
+       (magit-run-git "add" info))
+      ((untracked)
+       (apply #'magit-run-git "add" "--"
+              (magit-git-lines "ls-files" "--other" "--exclude-standard")))
+      ((unstaged diff hunk)
+       (if (magit-hunk-item-is-conflict-p item)
+           (error (concat "Can't stage individual resolution hunks.  "
+                          "Please stage the whole file.")))
+       (magit-apply-hunk-item item "--cached"))
+      ((unstaged diff)
+       (magit-run-git "add" "-u" (magit-diff-item-file item)))
+      ((staged *)
+       (error "Already staged"))
+      ((diff diff)
+       (save-excursion
+         (magit-goto-parent-section)
+         (magit-stage-item)))
+      ((diff diff hunk)
+       (save-excursion
+         (magit-goto-parent-section)
+         (magit-goto-parent-section)
+         (magit-stage-item)))
+      ((hunk)
+       (error "Can't stage this hunk"))
+      ((diff)
+       (error "Can't stage this diff")))))
+
+(defun magit-unstage-item ()
+  "Remove the item at point from the staging area."
+  (interactive)
+  (magit-section-action (item info "unstage")
+    ((staged diff hunk)
+     (magit-apply-hunk-item-reverse item "--cached"))
+    ((staged diff)
+     (if (eq (car info) 'unmerged)
+         (error "Can't unstage an unmerged file.  Resolve it first"))
+     (if (magit-no-commit-p)
+         (magit-run-git "rm" "--cached" "--" (magit-diff-item-file item))
+       (magit-run-git "reset" "-q" "HEAD" "--" (magit-diff-item-file item))))
+    ((unstaged *)
+     (error "Already unstaged"))
+    ((diff diff)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-unstage-item)))
+    ((diff diff hunk)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-goto-parent-section)
+       (magit-unstage-item)))
+    ((hunk)
+     (error "Can't unstage this hunk"))
+    ((diff)
+     (error "Can't unstage this diff"))))
+
+(defun magit-stage-all (&optional also-untracked-p)
+  "Add all remaining changes in tracked files to staging area.
+With prefix argument, add remaining untracked files as well.
+\('git add -u .' or 'git add .', respectively)."
+  (interactive "P")
+  (if also-untracked-p
+      (magit-run-git "add" ".")
+    (magit-run-git "add" "-u" ".")))
+
+(defun magit-unstage-all ()
+  "Remove all changes from staging area.
+\('git reset --mixed HEAD')."
+  (interactive)
+  (magit-run-git "reset" "HEAD"))
+
+;;; Branches
+
+(defun escape-branch-name (branch)
+  "Escapes branch names to remove problematic characters."
+  (replace-regexp-in-string "[/]" "-" branch))
+
+(defun magit-default-tracking-name-remote-plus-branch
+  (remote branch)
+  "Use the remote name plus a hyphen plus the escaped branch name for tracking branches."
+  (concat remote "-" (escape-branch-name branch)))
+
+(defun magit-default-tracking-name-branch-only
+  (remote branch)
+  "Use just the escaped branch name for tracking branches."
+  (escape-branch-name branch))
+
+(defun magit-get-tracking-name (remote branch)
+  "Given a REMOTE and a BRANCH name, ask the user for a local
+tracking brach name suggesting a sensible default."
+  (when (yes-or-no-p
+         (format "Create local tracking branch for %s? " branch))
+    (let* ((default-name
+             (funcall magit-default-tracking-name-function remote branch))
+           (chosen-name (read-string (format "Call local branch (%s): " default-name)
+                                     nil
+                                     nil
+                                     default-name)))
+      (when (magit-ref-exists-p (concat "refs/heads/" chosen-name))
+        (error "'%s' already exists." chosen-name))
+      chosen-name)))
+
+(defun magit-maybe-create-local-tracking-branch (rev)
+  "Depending on the users wishes, create a tracking branch for
+rev... maybe."
+  (if (string-match "^\\(?:refs/\\)?remotes/\\([^/]+\\)/\\(.+\\)" rev)
+      (let* ((remote (match-string 1 rev))
+             (branch (match-string 2 rev))
+             (tracker-name (magit-get-tracking-name remote branch)))
+        (when tracker-name
+          (magit-run-git "checkout" "-b" tracker-name rev)
+          t))
+    nil))
+
+(magit-define-command checkout (revision)
+  "Switch 'HEAD' to REVISION and update working tree.
+Fails if working tree or staging area contain uncommitted changes.
+If REVISION is a remote branch, offer to create a local tracking branch.
+\('git checkout [-b] REVISION')."
+  (interactive
+   (list (let ((current-branch (magit-get-current-branch))
+               (default (magit-default-rev)))
+           (magit-read-rev "Switch to"
+                           (unless (string= current-branch default)
+                             default)
+                           (if current-branch
+                               (cons (concat "refs/heads/" current-branch "$")
+                                     magit-uninteresting-refs)
+                             magit-uninteresting-refs)))))
+  (if revision
+      (when (not (magit-maybe-create-local-tracking-branch revision))
+        (magit-save-some-buffers)
+        (magit-run-git "checkout" (magit-rev-to-git revision))
+        (magit-update-vc-modeline default-directory))))
+
+(defun magit-read-create-branch-args ()
+  (let* ((cur-branch (magit-get-current-branch))
+         (cur-point (magit-default-rev))
+         (branch (read-string "Create branch: "))
+         (parent (magit-read-rev "Parent"
+                                 (cond
+                                  ((eq magit-create-branch-behaviour 'at-point) cur-point)
+                                  ((eq magit-create-branch-behaviour 'at-head) cur-branch)
+                                  (t cur-branch)))))
+    (list branch parent)))
+
+(magit-define-command create-branch (branch parent)
+  "Switch 'HEAD' to new BRANCH at revision PARENT and update working tree.
+Fails if working tree or staging area contain uncommitted changes.
+\('git checkout -b BRANCH REVISION')."
+  (interactive (magit-read-create-branch-args))
+  (when (and branch (not (string= branch ""))
+             parent)
+    (magit-save-some-buffers)
+    (magit-run-git "checkout" "-b"
+                   branch
+                   (append
+                    magit-custom-options
+                    (magit-rev-to-git parent)))
+    (magit-update-vc-modeline default-directory)))
+
+(defun magit-delete-branch (branch &optional force)
+  "Deletes a branch.
+If the branch is the current one, offers to switch to `master' first.
+With prefix, forces the removal even if it hasn't been merged.
+Works with local or remote branches.
+\('git branch [-d|-D] BRANCH' or 'git push <remote-part-of-BRANCH> :refs/heads/BRANCH')."
+  (interactive (list (magit-read-rev "Branch to delete" (magit-default-rev 'notrim))
+                     current-prefix-arg))
+  (let* ((remote (magit-remote-part-of-branch branch))
+         (is-current (string= branch (magit-get-current-branch)))
+         (args (list "branch"
+                     (if force "-D" "-d")
+                     branch)))
+    (cond
+     (remote
+      (magit-run-git "push" remote (concat ":refs/heads/" (magit-branch-no-remote branch))))
+     (is-current
+      (when (y-or-n-p "Cannot delete current branch. Switch to master first? ")
+          (progn
+            (magit-checkout "master")
+            (apply 'magit-run-git args))
+          (message "The current branch was not deleted.")))
+     (t
+            (apply 'magit-run-git args)))))
+
+(defun magit-move-branch (old new &optional force)
+  "Renames or moves a branch.
+With prefix, forces the move even if NEW already exists.
+\('git branch [-m|-M] OLD NEW')."
+  (interactive (list (magit-read-rev "Old name" (magit-default-rev))
+                     (read-string "New name: ")
+                     current-prefix-arg))
+  (magit-run-git "branch" (if force
+                              "-M"
+                            "-m")
+                 (magit-rev-to-git old) new))
+
+(defun magit-guess-branch ()
+  (magit-section-case (item info)
+    ((branch)
+     (magit-section-info (magit-current-section)))
+    ((wazzup commit)
+     (magit-section-info (magit-section-parent item)))
+    ((commit) (magit-name-rev (substring info 0 magit-sha1-abbrev-length)))
+    ((wazzup) info)))
+
+;;; Remotes
+
+(defun magit-add-remote (remote url)
+  "Adds a remote and fetches it.
+\('git remote add REMOTE URL')."
+  (interactive (list (read-string "Add remote: ")
+                     (read-string "URL: ")))
+  (magit-run-git "remote" "add" "-f" remote url))
+
+(defun magit-remove-remote (remote)
+  "Deletes a remote.
+\('git remote rm REMOTE')."
+  (interactive (list (magit-read-remote "Remote to delete")))
+  (magit-run-git "remote" "rm" remote))
+
+(defun magit-rename-remote (old new)
+  "Renames a remote.
+\('git remote rename OLD NEW')."
+  (interactive (list (magit-read-remote "Old name")
+                     (read-string "New name: ")))
+  (magit-run-git "remote" "rename" old new))
+
+(defun magit-guess-remote ()
+  (magit-section-case (item info)
+    ((branch)
+     (magit-section-info (magit-section-parent item)))
+    ((remote)
+     info)
+    (t
+     (if  (string= info ".")
+         info
+       (magit-get-current-remote)))))
+
+;;; Merging
+
+(defun magit-merge (revision)
+  "Merge REVISION into the current 'HEAD'; leave changes uncommitted.
+With a prefix-arg, the merge will be squashed.
+\('git merge --no-commit [--squash|--no-ff] REVISION')."
+  (interactive
+   (list (magit-read-rev "Merge" (magit-default-rev))))
+  (if revision
+      (apply 'magit-run-git
+             "merge"
+             (magit-rev-to-git revision)
+             magit-custom-options)))
+
+;;; Rebasing
+
+(defun magit-rebase-info ()
+  "Returns a list indicating the state of an in-progress rebase,
+if any."
+  (let ((git-dir (magit-git-dir)))
+    (cond ((file-exists-p (concat git-dir "rebase-merge"))
+           (list
+            ;; The commit we're rebasing onto, i.e. git rebase -i <onto>
+            (magit-name-rev (car (magit-file-lines (concat git-dir "rebase-merge/onto"))))
+
+            ;; How many commits we've gone through
+            (length (magit-file-lines (concat git-dir "rebase-merge/done")))
+
+            ;; How many commits we have in total, without the comments
+            ;; at the end of git-rebase-todo.backup
+            (let ((todo-lines-with-comments (magit-file-lines (concat git-dir "rebase-merge/git-rebase-todo.backup"))))
+              (loop for i in todo-lines-with-comments
+                    until (string= "" i)
+                    count i))))
+          ((and (file-exists-p (concat git-dir "rebase-apply"))
+                (file-exists-p (concat git-dir "rebase-apply/onto")))
+           ;; we might be here because a non-interactive rebase failed: the
+           ;; patches didn't apply cleanly
+           (list
+            ;; The commit we're rebasing onto, i.e. git rebase -i <onto>
+            (magit-name-rev (car (magit-file-lines (concat git-dir "rebase-apply/onto"))))
+
+            ;; How many commits we've gone through
+            (- (string-to-number (car (magit-file-lines (concat git-dir "rebase-apply/next")))) 1)
+
+            ;; How many commits we have in total
+            (string-to-number (car (magit-file-lines (concat git-dir "rebase-apply/last"))))
+            ))
+          (t nil))))
+
+(defun magit-rebase-step ()
+  (interactive)
+  (let ((info (magit-rebase-info)))
+    (if (not info)
+        (let* ((current-branch (magit-get-current-branch))
+               (rev (magit-read-rev "Rebase to"
+                                    (magit-format-ref (magit-remote-branch-for current-branch t))
+                                    (if current-branch
+                                        (cons (concat "refs/heads/" current-branch)
+                                              magit-uninteresting-refs)
+                                      magit-uninteresting-refs))))
+          (if rev
+              (magit-run-git "rebase" (magit-rev-to-git rev))))
+      (let ((cursor-in-echo-area t)
+            (message-log-max nil))
+        (message "Rebase in progress. [A]bort, [S]kip, or [C]ontinue? ")
+        (let ((reply (read-event)))
+          (case reply
+            ((?A ?a)
+             (magit-run-git-async "rebase" "--abort"))
+            ((?S ?s)
+             (magit-run-git-async "rebase" "--skip"))
+            ((?C ?c)
+             (magit-run-git-async "rebase" "--continue"))))))))
+
+;;; Resetting
+
+(magit-define-command reset-head (revision &optional hard)
+  "Switch 'HEAD' to REVISION, keeping prior working tree and staging area.
+Any differences from REVISION become new changes to be committed.
+With prefix argument, all uncommitted changes in working tree
+and staging area are lost.
+\('git reset [--soft|--hard] REVISION')."
+  (interactive (list (magit-read-rev (format "%s head to"
+                                             (if current-prefix-arg
+                                                 "Hard reset"
+                                               "Reset"))
+                                     (or (magit-default-rev)
+                                         "HEAD^"))
+                     current-prefix-arg))
+  (when revision
+    (magit-run-git "reset" (if hard "--hard" "--soft")
+                   (magit-rev-to-git revision))
+    (magit-update-vc-modeline default-directory)))
+
+(magit-define-command reset-head-hard (revision)
+  "Switch 'HEAD' to REVISION, losing all changes.
+Uncomitted changes in both working tree and staging area are lost.
+\('git reset --hard REVISION')."
+  (interactive (list (magit-read-rev (format "Hard reset head to")
+                                     (or (magit-default-rev)
+                                         "HEAD"))))
+  (magit-reset-head revision t))
+
+(magit-define-command reset-working-tree (&optional arg)
+  "Revert working tree and clear changes from staging area.
+\('git reset --hard HEAD').
+
+With a prefix arg, also remove untracked files.  With two prefix args, remove ignored files as well."
+  (interactive "p")
+  (let ((include-untracked (>= arg 4))
+        (include-ignored (>= arg 16)))
+    (when (yes-or-no-p (format "Discard all uncommitted changes%s%s? "
+                               (if include-untracked
+                                   ", untracked files"
+                                 "")
+                               (if include-ignored
+                                   ", ignored files"
+                                 "")))
+      (magit-reset-head-hard "HEAD")
+      (if include-untracked
+          (magit-run-git "clean" "-fd" (if include-ignored
+                                           "-x"
+                                         ""))))))
+
+;;; Rewriting
+
+(defun magit-read-rewrite-info ()
+  (when (file-exists-p (concat (magit-git-dir) "magit-rewrite-info"))
+    (with-temp-buffer
+      (insert-file-contents (concat (magit-git-dir) "magit-rewrite-info"))
+      (goto-char (point-min))
+      (read (current-buffer)))))
+
+(defun magit-write-rewrite-info (info)
+  (with-temp-file (concat (magit-git-dir) "magit-rewrite-info")
+    (prin1 info (current-buffer))
+    (princ "\n" (current-buffer))))
+
+(magit-define-inserter pending-commits ()
+  (let* ((info (magit-read-rewrite-info))
+         (pending (cdr (assq 'pending info))))
+    (when pending
+      (magit-with-section 'pending nil
+        (insert (propertize "Pending commits:\n"
+                            'face 'magit-section-title))
+        (dolist (p pending)
+          (let* ((commit (car p))
+                 (properties (cdr p))
+                 (used (plist-get properties 'used)))
+            (magit-with-section commit 'commit
+              (magit-set-section-info commit)
+              (insert (magit-git-string
+                       "log" "--max-count=1"
+                       (if used
+                           "--pretty=format:. %s"
+                         "--pretty=format:* %s")
+                       commit "--")
+                      "\n")))))
+      (insert "\n"))))
+
+(defun magit-rewrite-set-commit-property (commit prop value)
+  (let* ((info (magit-read-rewrite-info))
+         (pending (cdr (assq 'pending info)))
+         (p (assoc commit pending)))
+    (when p
+      (setf (cdr p) (plist-put (cdr p) prop value))
+      (magit-write-rewrite-info info)
+      (magit-need-refresh))))
+
+(defun magit-rewrite-set-used ()
+  (interactive)
+  (magit-section-action (item info)
+    ((pending commit)
+     (magit-rewrite-set-commit-property info 'used t))))
+
+(defun magit-rewrite-set-unused ()
+  (interactive)
+  (magit-section-action (item info)
+    ((pending commit)
+     (magit-rewrite-set-commit-property info 'used nil))))
+
+(magit-define-inserter pending-changes ()
+  (let* ((info (magit-read-rewrite-info))
+         (orig (cadr (assq 'orig info))))
+    (when orig
+      (let ((magit-hide-diffs t))
+        (magit-git-section 'pending-changes
+                           "Pending changes"
+                           'magit-wash-diffs
+                           "diff" (magit-diff-U-arg) "-R" orig)))))
+
+(defun magit-rewrite-start (from &optional onto)
+  (interactive (list (magit-read-rev "Rewrite from" (magit-default-rev))))
+  (or (magit-everything-clean-p)
+      (error "You have uncommitted changes"))
+  (or (not (magit-read-rewrite-info))
+      (error "Rewrite in progress"))
+  (let* ((orig (magit-rev-parse "HEAD"))
+         (base
+          (if
+              (or
+               (eq magit-rewrite-inclusive t)
+               (and
+                (eq magit-rewrite-inclusive 'ask)
+                (y-or-n-p "Include selected revision in rewrite? ")))
+              (or
+               (car (magit-commit-parents from))
+               (error "Can't rewrite a parentless commit."))
+            from))
+         (pending (magit-git-lines "rev-list" (concat base ".."))))
+    (magit-write-rewrite-info `((orig ,orig)
+                                (pending ,@(mapcar #'list pending))))
+    (magit-run-git "reset" "--hard" base)))
+
+(defun magit-rewrite-stop (&optional noconfirm)
+  (interactive)
+  (let* ((info (magit-read-rewrite-info)))
+    (or info
+        (error "No rewrite in progress"))
+    (when (or noconfirm
+              (yes-or-no-p "Stop rewrite? "))
+      (magit-write-rewrite-info nil)
+      (magit-refresh))))
+
+(defun magit-rewrite-abort ()
+  (interactive)
+  (let* ((info (magit-read-rewrite-info))
+         (orig (cadr (assq 'orig info))))
+    (or info
+        (error "No rewrite in progress"))
+    (or (magit-everything-clean-p)
+        (error "You have uncommitted changes"))
+    (when (yes-or-no-p "Abort rewrite? ")
+      (magit-write-rewrite-info nil)
+      (magit-run-git "reset" "--hard" orig))))
+
+(defun magit-rewrite-finish ()
+  (interactive)
+  (magit-with-refresh
+    (magit-rewrite-finish-step t)))
+
+(defun magit-rewrite-finish-step (first-p)
+  (let ((info (magit-read-rewrite-info)))
+    (or info
+        (error "No rewrite in progress"))
+    (let* ((pending (cdr (assq 'pending info)))
+           (first-unused
+            (let ((rpend (reverse pending)))
+              (while (and rpend (plist-get (cdr (car rpend)) 'used))
+                (setq rpend (cdr rpend)))
+              (car rpend)))
+           (commit (car first-unused)))
+      (cond ((not first-unused)
+             (magit-rewrite-stop t))
+            ((magit-apply-commit commit t (not first-p))
+             (magit-rewrite-set-commit-property commit 'used t)
+             (magit-rewrite-finish-step nil))))))
+
+;;; Updating, pull, and push
+
+(magit-define-command fetch (remote)
+  "Fetch from REMOTE."
+  (interactive (list (magit-read-remote)))
+  (apply 'magit-run-git-async "fetch" remote magit-custom-options))
+
+(magit-define-command fetch-current ()
+  "Run fetch for default remote.
+
+If there is no default remote, ask for one."
+  (interactive)
+  (magit-fetch (or (magit-get-current-remote)
+                   (magit-read-remote))))
+
+(magit-define-command remote-update ()
+  "Update all remotes."
+  (interactive)
+  (apply 'magit-run-git-async "remote" "update" magit-custom-options))
+
+(magit-define-command pull ()
+  "Run git pull against the current remote."
+  (interactive)
+  (let* ((branch (magit-get-current-branch))
+         (branch-remote (magit-get-remote branch))
+         (config-branch (and branch (magit-get "branch" branch "merge")))
+         (merge-branch (or (and config-branch (not current-prefix-arg))
+                           (magit-read-remote-branch
+                            branch-remote (format "Pull from: ")))))
+    (when (and branch (not config-branch))
+      (magit-set branch-remote "branch" branch "remote")
+      (magit-set (format "refs/heads/%s" merge-branch)
+                 "branch" branch "merge"))
+    (apply 'magit-run-git-async "pull" "-v" magit-custom-options)))
+
+(eval-when-compile (require 'eshell))
+
+(defun magit-parse-arguments (command)
+  (require 'eshell)
+  (with-temp-buffer
+    (insert command)
+    (mapcar 'eval (eshell-parse-arguments (point-min) (point-max)))))
+
+(defun magit-shell-command (command)
+  "Perform arbitrary shell COMMAND."
+  (interactive "sCommand: ")
+  (let ((args (magit-parse-arguments command))
+        (magit-process-popup-time 0))
+    (magit-run* args nil nil nil t)))
+
+(defvar magit-git-command-history nil)
+
+(defun magit-git-command (command)
+  "Perform arbitrary Git COMMAND.
+
+Similar to `magit-shell-command', but involves slightly less
+typing and automatically refreshes the status buffer."
+  (interactive
+   (list (read-string "Run git like this: " nil 'magit-git-command-history)))
+  (require 'pcomplete)
+  (let ((args (magit-parse-arguments command))
+        (magit-process-popup-time 0))
+    (magit-with-refresh
+      (magit-run* (append (cons magit-git-executable
+                                magit-git-standard-options)
+                          args)
+                  nil nil nil t))))
+
+(magit-define-command push-tags ()
+  "Push tags."
+  (interactive)
+  (magit-run-git-async "push" "--tags"))
+
+(magit-define-command push ()
+  "Push the current branch to a remote repository.
+
+With no prefix argument, ask `magit-get-remote' what remote to
+use for this branch.
+
+With a prefix arg \(e.g., \\[universal-argument] \\[magit-push]), \
+ask user instead.
+
+With \\[universal-argument] \\[universal-argument] as prefix, \
+also prompt user for the remote branch;
+otherwise, try to use the branch.<name>.merge git-config(1)
+option, falling back to something hairy if that is unset."
+  (interactive)
+  (let* ((branch (or (magit-get-current-branch)
+                     (error "Don't push a detached head.  That's gross")))
+         (branch-remote (magit-get-remote branch))
+         (push-remote (if (or current-prefix-arg
+                              (not branch-remote))
+                          (magit-read-remote (format "Push %s to remote"
+                                                     branch)
+                                             branch-remote)
+                        branch-remote))
+         (ref-branch (or (and (>= (prefix-numeric-value current-prefix-arg) 16)
+                              (magit-read-remote-branch
+                               push-remote (format "Push %s as branch" branch)))
+                         (magit-get "branch" branch "merge"))))
+    (if (and (not ref-branch)
+             (eq magit-set-upstream-on-push 'refuse))
+        (error "Not pushing since no upstream has been set.")
+      (let ((set-upstream-on-push (and (not ref-branch)
+                                       (or (eq magit-set-upstream-on-push 'dontask)
+                                           (and (eq magit-set-upstream-on-push t)
+                                                (yes-or-no-p "Set upstream while pushing? "))))))
+        (if (and (not branch-remote)
+                 (not current-prefix-arg))
+            (magit-set push-remote "branch" branch "remote"))
+        (apply 'magit-run-git-async "push" "-v" push-remote
+               (if ref-branch
+                   (format "%s:%s" branch ref-branch)
+                 branch)
+               (if set-upstream-on-push
+                   (cons "--set-upstream" magit-custom-options)
+                 magit-custom-options))
+        ;; Although git will automatically set up the remote,
+        ;; it doesn't set up the branch to merge (at least as of Git 1.6.6.1),
+        ;; so we have to do that manually.
+        (unless ref-branch
+          (magit-set (concat "refs/heads/" branch) "branch" branch "merge"))))))
+
+;;; Log edit mode
+
+(defvar magit-log-edit-buffer-name "*magit-edit-log*"
+  "Buffer name for composing commit messages.")
+
+(defvar magit-log-edit-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-c") 'magit-log-edit-commit)
+    (define-key map (kbd "C-x #") 'magit-log-edit-commit)
+    (define-key map (kbd "C-c C-a") 'magit-log-edit-toggle-amending)
+    (define-key map (kbd "C-c C-s") 'magit-log-edit-toggle-signoff)
+    (define-key map (kbd "C-c C-t") 'magit-log-edit-toggle-author)
+    (define-key map (kbd "C-c C-e") 'magit-log-edit-toggle-allow-empty)
+    (define-key map (kbd "M-p") 'log-edit-previous-comment)
+    (define-key map (kbd "M-n") 'log-edit-next-comment)
+    (define-key map (kbd "C-c C-k") 'magit-log-edit-cancel-log-message)
+    (define-key map (kbd "C-c C-]") 'magit-log-edit-cancel-log-message)
+    (define-key map (kbd "C-x C-s") (lambda ()
+                                      (interactive)
+                                      (message "Not saved. Use C-c C-c to finalize this commit message.")))
+    map))
+
+(defvar magit-pre-log-edit-window-configuration nil)
+
+(define-derived-mode magit-log-edit-mode text-mode "Magit Log Edit"
+  ;; Recognize changelog-style paragraphs
+  (set (make-local-variable 'paragraph-start)
+       (concat paragraph-start "\\|*\\|(")))
+
+(defun magit-log-edit-cleanup ()
+  (save-excursion
+    (goto-char (point-min))
+    (goto-char (point-min))
+    (if (re-search-forward "[ \t\n]*\\'" nil t)
+        (replace-match "\n" nil nil))))
+
+(defun magit-log-edit-append (str)
+  (with-current-buffer (get-buffer-create magit-log-edit-buffer-name)
+    (goto-char (point-max))
+    (insert str "\n")))
+
+(defconst magit-log-header-end "-- End of Magit header --\n")
+
+(defun magit-log-edit-get-fields ()
+  (let ((buf (get-buffer magit-log-edit-buffer-name))
+        (result nil))
+    (if buf
+        (with-current-buffer buf
+          (goto-char (point-min))
+          (while (looking-at "^\\([A-Za-z0-9-_]+\\): *\\(.+\\)?$")
+            (setq result (acons (intern (downcase (match-string 1)))
+                                (read (or (match-string 2) "nil"))
+                                result))
+            (forward-line))
+          (if (not (looking-at (regexp-quote magit-log-header-end)))
+              (setq result nil))))
+    (nreverse result)))
+
+(defun magit-log-edit-set-fields (fields)
+  (let ((buf (get-buffer-create magit-log-edit-buffer-name)))
+    (with-current-buffer buf
+      (goto-char (point-min))
+      (if (search-forward-regexp (format "^\\([A-Za-z0-9-_]+:.*\n\\)*%s"
+                                         (regexp-quote magit-log-header-end))
+                                 nil t)
+          (delete-region (match-beginning 0) (match-end 0)))
+      (goto-char (point-min))
+      (when fields
+        (while fields
+          (insert (capitalize (symbol-name (caar fields))) ": "
+                  (prin1-to-string (cdar fields)) "\n")
+          (setq fields (cdr fields)))
+        (insert magit-log-header-end)))))
+
+(defun magit-log-edit-set-field (name value)
+  (let* ((fields (magit-log-edit-get-fields))
+         (cell (assq name fields)))
+    (cond (cell
+           (if value
+               (rplacd cell value)
+             (setq fields (delq cell fields))))
+          (t
+           (if value
+               (setq fields (append fields (list (cons name value)))))))
+    (magit-log-edit-set-fields fields)))
+
+(defun magit-log-edit-get-field (name)
+  (cdr (assq name (magit-log-edit-get-fields))))
+
+(defun magit-log-edit-toggle-field (name default)
+  "Toggle the log-edit field named NAME.
+If it's currently unset, set it to DEFAULT (t or nil).
+
+Return nil if the field is toggled off, and non-nil if it's
+toggled on.  When it's toggled on for the first time, return
+'first."
+  (let* ((fields (magit-log-edit-get-fields))
+         (cell (assq name fields)) yesp)
+    (if cell
+        (progn
+          (setq yesp (equal (cdr cell) "yes"))
+          (rplacd cell (if yesp "no" "yes")))
+      (setq fields (acons name (if default "yes" "no") fields))
+      (setq yesp (if default 'first)))
+    (magit-log-edit-set-fields fields)
+    yesp))
+
+(defun magit-log-edit-toggle-input (name default)
+  "Toggle the log-edit input named NAME.
+If it's currently unset, set it to DEFAULT (a string). If it is
+set remove it.
+
+Return nil if the input is toggled off, and its valud if it's
+toggled on."
+  (let* ((fields (magit-log-edit-get-fields))
+         (cell (assq name fields))
+         result)
+    (if cell
+        (progn
+          (setq fields (assq-delete-all name fields)
+                result (cdr cell)))
+      (setq fields (acons name default fields)))
+    (magit-log-edit-set-fields fields)
+    result))
+
+(defun magit-log-edit-setup-author-env (author)
+  "Set GIT_AUTHOR_* variables from AUTHOR spec.
+If AUTHOR is nil, honor default values from
+environment (potentially empty)."
+  (when author
+    ;; XXX - this is a bit strict, probably.
+    (or (string-match "\\(.*\\) <\\(.*\\)>\\(?:,\\s-*\\(.+\\)\\)?" author)
+        (error "Can't parse author string"))
+    ;; Shucks, setenv destroys the match data.
+    (let ((name (match-string 1 author))
+          (email (match-string 2 author))
+          (date  (match-string 3 author)))
+      (make-local-variable 'process-environment)
+      (setenv "GIT_AUTHOR_NAME" name)
+      (setenv "GIT_AUTHOR_EMAIL" email)
+      (if date
+          (setenv "GIT_AUTHOR_DATE" date)))))
+
+(defun magit-log-edit-push-to-comment-ring (comment)
+  (when (or (ring-empty-p log-edit-comment-ring)
+            (not (equal comment (ring-ref log-edit-comment-ring 0))))
+    (ring-insert log-edit-comment-ring comment)))
+
+(defun magit-log-edit-commit ()
+  "Finish edits and create new commit object.
+\('git commit ...')"
+  (interactive)
+  (let* ((fields (magit-log-edit-get-fields))
+         (amend (equal (cdr (assq 'amend fields)) "yes"))
+         (allow-empty (equal (cdr (assq 'allow-empty fields)) "yes"))
+         (commit-all (equal (cdr (assq 'commit-all fields)) "yes"))
+         (sign-off-field (assq 'sign-off fields))
+         (sign-off (if sign-off-field
+                       (equal (cdr sign-off-field) "yes")
+                     magit-commit-signoff))
+         (tag-rev (cdr (assq 'tag-rev fields)))
+         (tag-name (cdr (assq 'tag-name fields)))
+         (author (cdr (assq 'author fields)))
+         (tag-options (cdr (assq 'tag-options fields))))
+
+    (unless (or (magit-anything-staged-p)
+                allow-empty
+                amend
+                tag-name
+                (file-exists-p (concat (magit-git-dir) "MERGE_HEAD"))
+                (and commit-all
+                     (not (magit-everything-clean-p))))
+      (error "Refusing to create empty commit. Maybe you want to amend (%s) or allow-empty (%s)?"
+             (key-description (car (where-is-internal
+                                    'magit-log-edit-toggle-amending)))
+             (key-description (car (where-is-internal
+                                    'magit-log-edit-toggle-allow-empty)))))
+
+    (magit-log-edit-push-to-comment-ring (buffer-string))
+    (magit-log-edit-setup-author-env author)
+    (magit-log-edit-set-fields nil)
+    (magit-log-edit-cleanup)
+    (if (= (buffer-size) 0)
+        (insert "(Empty description)\n"))
+    (let ((env process-environment)
+          (commit-buf (current-buffer)))
+      (with-current-buffer (magit-find-status-buffer default-directory)
+        (let ((process-environment env))
+          (cond (tag-name
+                 (apply #'magit-run-git-with-input commit-buf
+                        "tag" (append tag-options (list tag-name "-a" "-F" "-" tag-rev))))
+                (t
+                 (apply #'magit-run-async-with-input commit-buf
+                        magit-git-executable
+                        (append magit-git-standard-options
+                                '("commit")
+                                magit-custom-options
+                                '("-F" "-")
+                                (if (and commit-all (not allow-empty)) '("--all") '())
+                                (if amend '("--amend") '())
+                                (if allow-empty '("--allow-empty"))
+                                (if sign-off '("--signoff") '()))))))))
+    ;; shouldn't we kill that buffer altogether?
+    (erase-buffer)
+    (let ((magit-buf magit-buffer-internal))
+      (bury-buffer)
+      (set-buffer magit-buf))
+    (when (file-exists-p (concat (magit-git-dir) "MERGE_MSG"))
+      (delete-file (concat (magit-git-dir) "MERGE_MSG")))
+    ;; potentially the local environment has been altered with settings that
+    ;; were specific to this commit. Let's revert it
+    (kill-local-variable 'process-environment)
+    (magit-update-vc-modeline default-directory)
+    (when magit-pre-log-edit-window-configuration
+      (set-window-configuration magit-pre-log-edit-window-configuration)
+      (setq magit-pre-log-edit-window-configuration nil))))
+
+(defun magit-log-edit-cancel-log-message ()
+  "Abort edits and erase commit message being composed."
+  (interactive)
+  (when (or (not magit-log-edit-confirm-cancellation)
+            (yes-or-no-p
+             "Really cancel editing the log (any changes will be lost)?"))
+    (erase-buffer)
+    (bury-buffer)
+    (when magit-pre-log-edit-window-configuration
+      (set-window-configuration magit-pre-log-edit-window-configuration)
+      (setq magit-pre-log-edit-window-configuration nil))))
+
+(defun magit-log-edit-toggle-amending ()
+  "Toggle whether this will be an amendment to the previous commit.
+\(i.e., whether eventual commit does 'git commit --amend')"
+  (interactive)
+  (when (eq (magit-log-edit-toggle-field 'amend t) 'first)
+    (magit-log-edit-append
+     (magit-trim-line (magit-format-commit "HEAD" "%s%n%n%b")))))
+
+(defun magit-log-edit-toggle-signoff ()
+  "Toggle whether this commit will include a signoff.
+\(i.e., whether eventual commit does 'git commit --signoff')"
+  (interactive)
+  (magit-log-edit-toggle-field 'sign-off (not magit-commit-signoff)))
+
+(defun magit-log-edit-toggle-author ()
+  "Toggle whether this commit will include an author.
+\(i.e., whether eventual commit is run with GIT_AUTHOR_NAME and
+GIT_AUTHOR_EMAIL set)"
+  (interactive)
+  (magit-log-edit-toggle-input 'author (format "%s <%s>"
+                                               (or (magit-get "user" "name") "Author Name")
+                                               (or (magit-get "user" "email") "author@email"))))
+
+(defun magit-log-edit-toggle-allow-empty ()
+  "Toggle whether this commit is allowed to be empty.
+This means that the eventual commit does 'git commit --allow-empty'."
+  (interactive)
+  (magit-log-edit-toggle-field 'allow-empty t))
+
+(defun magit-pop-to-log-edit (operation)
+  (let ((dir default-directory)
+        (magit-buf (current-buffer))
+        (buf (get-buffer-create magit-log-edit-buffer-name)))
+    (setq magit-pre-log-edit-window-configuration
+          (current-window-configuration))
+    (pop-to-buffer buf)
+    (setq default-directory dir)
+    (when (file-exists-p (concat (magit-git-dir) "MERGE_MSG"))
+      (insert-file-contents (concat (magit-git-dir) "MERGE_MSG")))
+    (magit-log-edit-mode)
+    (make-local-variable 'magit-buffer-internal)
+    (setq magit-buffer-internal magit-buf)
+    (message "Type C-c C-c to %s (C-c C-k to cancel)." operation)))
+
+(defun magit-log-edit (&optional arg)
+  "Brings up a buffer to allow editing of commit messages.
+
+Giving a simple prefix arg will amend a previous commit, while
+a double prefix arg will allow creating an empty one.
+
+If there is a rebase in progress, offer the user the option to
+continue it.
+
+\\{magit-log-edit-mode-map}"
+  (interactive "P")
+  ;; If repository is dirty there is no point in trying to
+  ;; suggest to continue the rebase. Git will rebuke you and exit with
+  ;; error code, so suggest it only if theres absolutely nothing else
+  ;; to do and rebase is ongoing.
+  (if (and (magit-everything-clean-p)
+           (magit-rebase-info)
+           (y-or-n-p "Rebase in progress.  Continue it? "))
+      (magit-run-git-async "rebase" "--continue")
+
+    ;; If there's nothing staged, set commit flag to `nil', thus
+    ;; avoiding unnescessary popping up of the log edit buffer in case
+    ;; when user chose to forgo commiting all unstaged changes
+    (let ((amend-p (= (prefix-numeric-value arg) 4))
+          (empty-p (= (prefix-numeric-value arg) 16)))
+      (when (and magit-commit-all-when-nothing-staged
+                 (not (magit-everything-clean-p))
+                 (not (magit-anything-staged-p)))
+        (cond ((eq magit-commit-all-when-nothing-staged 'ask-stage)
+               (when (y-or-n-p "Nothing staged.  Stage everything now? ")
+                 (magit-stage-all)))
+              ((not (magit-log-edit-get-field 'commit-all))
+               (when (or (eq magit-commit-all-when-nothing-staged t)
+                         (y-or-n-p
+                          "Nothing staged.  Commit all unstaged changes? "))
+                 (magit-log-edit-set-field 'commit-all "yes")))))
+      (when amend-p
+        (magit-log-edit-toggle-amending))
+      (when empty-p
+        (magit-log-edit-toggle-allow-empty))
+      (let ((author-email (or (getenv "GIT_AUTHOR_EMAIL") ""))
+            (author-name (or (getenv "GIT_AUTHOR_NAME") ""))
+            (author-date (or (getenv "GIT_AUTHOR_DATE") "")))
+        (if (not (string= author-email ""))
+            (magit-log-edit-set-field 'author (format "%s <%s>%s"
+                                                      (if (string= "" author-name) author-email author-name)
+                                                      author-email
+                                                      (if (string= "" author-date) "" (format ", %s" author-date))))))
+      (magit-pop-to-log-edit "commit"))))
+
+(defun magit-add-log ()
+  (interactive)
+  (cond ((magit-rebase-info)
+         (if (y-or-n-p "Rebase in progress.  Continue it? ")
+             (magit-run-git-async "rebase" "--continue")))
+        (t
+         (let ((section (magit-current-section)))
+           (let ((fun (if (eq (magit-section-type section) 'hunk)
+                          (save-window-excursion
+                            (save-excursion
+                              (magit-visit-item)
+                              (add-log-current-defun)))
+                        nil))
+                 (file (magit-diff-item-file
+                        (cond ((eq (magit-section-type section) 'hunk)
+                               (magit-hunk-item-diff section))
+                              ((eq (magit-section-type section) 'diff)
+                               section)
+                              (t
+                               (error "No change at point"))))))
+             (magit-log-edit nil)
+             (goto-char (point-min))
+             (cond ((not (search-forward-regexp
+                          (format "^\\* %s" (regexp-quote file)) nil t))
+                    ;; No entry for file, create it.
+                    (goto-char (point-max))
+                    (insert (format "\n* %s" file))
+                    (if fun
+                        (insert (format " (%s)" fun)))
+                    (insert ": "))
+                   (fun
+                    ;; found entry for file, look for fun
+                    (let ((limit (or (save-excursion
+                                       (and (search-forward-regexp "^\\* "
+                                                                   nil t)
+                                            (match-beginning 0)))
+                                     (point-max))))
+                      (cond ((search-forward-regexp (format "(.*\\<%s\\>.*):"
+                                                            (regexp-quote fun))
+                                                    limit t)
+                             ;; found it, goto end of current entry
+                             (if (search-forward-regexp "^(" limit t)
+                                 (backward-char 2)
+                               (goto-char limit)))
+                            (t
+                             ;; not found, insert new entry
+                             (goto-char limit)
+                             (if (bolp)
+                                 (open-line 1)
+                               (newline))
+                             (insert (format "(%s): " fun))))))
+                   (t
+                    ;; found entry for file, look for beginning  it
+                    (when (looking-at ":")
+                      (forward-char 2)))))))))
+
+;;; Tags
+
+(magit-define-command tag (name rev)
+  "Create a new lightweight tag with the given NAME at REV.
+\('git tag NAME')."
+  (interactive
+   (list
+    (read-string "Tag name: ")
+    (magit-read-rev "Place tag on: " (or (magit-default-rev) "HEAD"))))
+  (apply #'magit-run-git "tag" (append magit-custom-options (list name rev))))
+
+(magit-define-command annotated-tag (name rev)
+  "Start composing an annotated tag with the given NAME.
+Tag will point to the current 'HEAD'."
+  (interactive
+   (list
+    (read-string "Tag name: ")
+    (magit-read-rev "Place tag on: " (or (magit-default-rev) "HEAD"))))
+  (magit-log-edit-set-field 'tag-name name)
+  (magit-log-edit-set-field 'tag-rev rev)
+  (magit-log-edit-set-field 'tag-options magit-custom-options)
+  (magit-pop-to-log-edit "tag"))
+
+;;; Stashing
+
+(defun magit-wash-stash ()
+  (if (search-forward-regexp "stash@{\\(.*?\\)}" (line-end-position) t)
+      (let ((stash (match-string-no-properties 0))
+            (name (match-string-no-properties 1)))
+        (delete-region (match-beginning 0) (match-end 0))
+        (goto-char (match-beginning 0))
+        (fixup-whitespace)
+        (goto-char (line-beginning-position))
+        (insert name)
+        (goto-char (line-beginning-position))
+        (magit-with-section stash 'stash
+          (magit-set-section-info stash)
+          (forward-line)))
+    (forward-line))
+  t)
+
+(defun magit-wash-stashes ()
+  (let ((magit-old-top-section nil))
+    (magit-wash-sequence #'magit-wash-stash)))
+
+(magit-define-inserter stashes ()
+  (magit-git-section 'stashes
+                     "Stashes:" 'magit-wash-stashes
+                     "stash" "list"))
+
+(magit-define-command stash (description)
+  "Create new stash of working tree and staging area named DESCRIPTION.
+Working tree and staging area revert to the current 'HEAD'.
+With prefix argument, changes in staging area are kept.
+\('git stash save [--keep-index] DESCRIPTION')"
+  (interactive "sStash description: ")
+  (apply 'magit-run-git `("stash" "save" ,@magit-custom-options "--" ,description)))
+
+(magit-define-command stash-snapshot ()
+  "Create new stash of working tree and staging area; keep changes in place.
+\('git stash save \"Snapshot...\"; git stash apply stash@{0}')"
+  (interactive)
+  (magit-with-refresh
+    (apply 'magit-run-git `("stash" "save" ,@magit-custom-options
+                   ,(format-time-string "Snapshot taken at %Y-%m-%d %H:%M:%S"
+                                       (current-time))))
+    (magit-run-git "stash" "apply" "stash@{0}")))
+
+(defvar magit-currently-shown-stash nil)
+
+(define-derived-mode magit-stash-mode magit-mode "Magit Stash"
+  "Mode for looking at a git stash.
+
+\\{magit-stash-mode-map}"
+  :group 'magit)
+
+(defvar magit-stash-buffer-name "*magit-stash*"
+  "Buffer name for displaying a stash.")
+
+(defun magit-show-stash (stash &optional scroll)
+  (when (magit-section-p stash)
+    (setq stash (magit-section-info stash)))
+  (let ((dir default-directory)
+        (buf (get-buffer-create magit-stash-buffer-name))
+        (stash-id (magit-git-string "rev-list" "-1" stash)))
+    (cond ((and (equal magit-currently-shown-stash stash-id)
+                (with-current-buffer buf
+                  (> (length (buffer-string)) 1)))
+           (let ((win (get-buffer-window buf)))
+             (cond ((not win)
+                    (display-buffer buf))
+                   (scroll
+                    (with-selected-window win
+                      (funcall scroll))))))
+          (t
+           (setq magit-currently-shown-stash stash-id)
+           (display-buffer buf)
+           (with-current-buffer buf
+             (set-buffer buf)
+             (goto-char (point-min))
+             (let* ((range (cons (concat stash "^2^") stash))
+                    (magit-current-diff-range range)
+                    (args (magit-rev-range-to-git range)))
+               (magit-mode-init dir 'magit-diff-mode #'magit-refresh-diff-buffer
+                                range args)))))))
+;;; Commits
+
+(defun magit-commit-at-point (&optional nil-ok-p)
+  (let* ((section (magit-current-section))
+         (commit (if (and section
+                          (eq (magit-section-type section) 'commit))
+                     (magit-section-info section)
+                 (get-text-property (point) 'revision))))
+    (if nil-ok-p
+        commit
+      (or commit
+          (error "No commit at point")))))
+
+(defun magit-apply-commit (commit &optional docommit noerase revert)
+  (let* ((parent-id (magit-choose-parent-id commit "cherry-pick"))
+         (success (magit-run* `(,magit-git-executable
+                                ,@magit-git-standard-options
+                                ,(if revert "revert" "cherry-pick")
+                                ,@(if parent-id
+                                      (list "-m" (number-to-string parent-id)))
+                                ,@(if (not docommit) (list "--no-commit"))
+                                ,commit)
+                              nil noerase)))
+    (when (and (not docommit) success)
+      (cond (revert
+             (magit-log-edit-append
+              (magit-format-commit commit "Reverting \"%s\"")))
+            (t
+             (magit-log-edit-append
+              (magit-format-commit commit "%s%n%n%b"))
+             (magit-log-edit-set-field
+              'author
+              (magit-format-commit commit "%an <%ae>, %ai")))))
+    success))
+
+(defun magit-apply-item ()
+  (interactive)
+  (magit-section-action (item info "apply")
+    ((pending commit)
+     (magit-apply-commit info)
+     (magit-rewrite-set-commit-property info 'used t))
+    ((commit)
+     (magit-apply-commit info))
+    ((unstaged *)
+     (error "Change is already in your working tree"))
+    ((staged *)
+     (error "Change is already in your working tree"))
+    ((hunk)
+     (magit-apply-hunk-item item))
+    ((diff)
+     (magit-apply-diff-item item))
+    ((stash)
+     (magit-run-git "stash" "apply" info))))
+
+(defun magit-cherry-pick-item ()
+  (interactive)
+  (magit-section-action (item info "cherry-pick")
+    ((pending commit)
+     (magit-apply-commit info t)
+     (magit-rewrite-set-commit-property info 'used t))
+    ((commit)
+     (magit-apply-commit info t))
+    ((stash)
+     (magit-run-git "stash" "pop" info))))
+
+(defmacro magit-with-revert-confirmation (&rest body)
+  `(when (or (not magit-revert-item-confirm)
+             (yes-or-no-p "Really revert this item? "))
+     ,@body))
+
+(defun magit-revert-item ()
+  (interactive)
+  (magit-section-action (item info "revert")
+    ((pending commit)
+     (magit-with-revert-confirmation
+      (magit-apply-commit info nil nil t)
+      (magit-rewrite-set-commit-property info 'used nil)))
+    ((commit)
+     (magit-with-revert-confirmation
+      (magit-apply-commit info nil nil t)))
+    ;; Reverting unstaged changes cannot be undone
+    ((unstaged *)
+     (magit-discard-item))
+    ((hunk)
+     (magit-with-revert-confirmation
+      (magit-apply-hunk-item-reverse item)))
+    ((diff)
+     (magit-with-revert-confirmation
+      (magit-apply-diff-item item "--reverse")))))
+
+(defun magit-log-show-more-entries (&optional arg)
+  "Grow the number of log entries shown.
+
+With no prefix optional ARG, show twice as many log entries.
+With a numerical prefix ARG, add this number to the number of shown log entries.
+With a non numeric prefix ARG, show all entries"
+  (interactive "P")
+  (make-local-variable 'magit-log-cutoff-length)
+  (cond
+   ((numberp arg)
+    (setq magit-log-cutoff-length (+ magit-log-cutoff-length arg)))
+   (arg
+    (setq magit-log-cutoff-length magit-log-infinite-length))
+   (t (setq magit-log-cutoff-length (* magit-log-cutoff-length 2))))
+  (let ((old-point (point)))
+    (magit-refresh)
+    (goto-char old-point)))
+
+(defun magit-refresh-log-buffer (range style args)
+  (magit-configure-have-graph)
+  (magit-configure-have-decorate)
+  (magit-configure-have-abbrev)
+  (setq magit-current-range range)
+  (magit-create-log-buffer-sections
+    (apply #'magit-git-section nil
+           (magit-rev-range-describe range "Commits")
+           (apply-partially 'magit-wash-log style)
+           `("log"
+             ,(format "--max-count=%s" magit-log-cutoff-length)
+             ,"--abbrev-commit"
+             ,(format "--abbrev=%s" magit-sha1-abbrev-length)
+             ,@(cond ((eq style 'long) (list "--stat" "-z"))
+                     ((eq style 'oneline) (list "--pretty=oneline"))
+                     (t nil))
+             ,@(if magit-have-decorate (list "--decorate=full"))
+             ,@(if magit-have-graph (list "--graph"))
+             ,@args
+             "--"))))
+
+(define-derived-mode magit-log-mode magit-mode "Magit Log"
+  "Mode for looking at git log.
+
+\\{magit-log-mode-map}"
+  :group 'magit)
+
+(defvar magit-log-buffer-name "*magit-log*"
+  "Buffer name for display of log entries.")
+
+(magit-define-command log-ranged ()
+  (interactive)
+  (magit-log t))
+(define-obsolete-function-alias 'magit-display-log-ranged 'magit-log-ranged)
+
+(magit-define-command log (&optional ask-for-range &rest extra-args)
+  (interactive)
+  (let* ((log-range (if ask-for-range
+                        (magit-read-rev-range "Log" "HEAD")
+                      "HEAD"))
+         (topdir (magit-get-top-dir default-directory))
+         (args (nconc (list (magit-rev-range-to-git log-range))
+                      magit-custom-options
+                      extra-args)))
+    (magit-buffer-switch magit-log-buffer-name)
+    (magit-mode-init topdir 'magit-log-mode #'magit-refresh-log-buffer log-range
+                     'oneline args)))
+
+(define-obsolete-function-alias 'magit-display-log 'magit-log)
+
+(magit-define-command log-long-ranged ()
+  (interactive)
+  (magit-log-long t))
+
+(magit-define-command log-long (&optional ranged)
+  (interactive)
+  (let* ((range (if ranged
+                    (magit-read-rev-range "Long log" "HEAD")
+                  "HEAD"))
+         (topdir (magit-get-top-dir default-directory))
+         (args (append (list (magit-rev-range-to-git range))
+                       magit-custom-options)))
+    (magit-buffer-switch magit-log-buffer-name)
+    (magit-mode-init topdir 'magit-log-mode #'magit-refresh-log-buffer range
+                     'long args)))
+
+;;; Reflog
+
+(defvar magit-reflog-head nil
+  "The HEAD of the reflog in the current buffer.
+This is only non-nil in reflog buffers.")
+(make-variable-buffer-local 'magit-reflog-head)
+
+(defun magit-refresh-reflog-buffer (head args)
+  (setq magit-reflog-head head)
+  (magit-create-log-buffer-sections
+    (apply #'magit-git-section
+           'reflog (format "Local history of head %s" head) 'magit-wash-log "log"
+           (append magit-git-log-options
+                   (list
+                    "--walk-reflogs"
+                    (format "--max-count=%s" magit-log-cutoff-length)
+                    args)))))
+
+(define-derived-mode magit-reflog-mode magit-log-mode "Magit Reflog"
+  "Mode for looking at git reflog.
+
+\\{magit-reflog-mode-map}"
+  :group 'magit)
+
+(magit-define-command reflog (&optional ask-for-range)
+  (interactive)
+  (let ((at (or (if ask-for-range
+                    (magit-read-rev "Reflog of" (or (magit-guess-branch) "HEAD")))
+                "HEAD")))
+    (let* ((topdir (magit-get-top-dir default-directory))
+           (args (magit-rev-to-git at)))
+      (magit-buffer-switch "*magit-reflog*")
+      (magit-mode-init topdir 'magit-reflog-mode
+                       #'magit-refresh-reflog-buffer at args))))
+
+(magit-define-command reflog-ranged ()
+  (interactive)
+  (magit-reflog t))
+
+;;; Diffing
+
+(defvar magit-ediff-buffers nil
+  "List of buffers that may be killed by `magit-ediff-restore'.")
+
+(defvar magit-ediff-windows nil
+  "The window configuration that will be restored when Ediff is finished.")
+
+(defun magit-ediff()
+  "View the current DIFF section in ediff."
+  (interactive)
+  (let ((diff (magit-current-section)))
+    (when (magit-section-hidden diff)
+      ;; Range is not set until the first time the diff is visible.
+      ;; This somewhat hackish code makes sure it's been visible at least once.
+      (magit-toggle-section)
+      (magit-toggle-section)
+      (setq diff (magit-current-section)))
+    (if (eq 'hunk (magit-section-type diff))
+        (setq diff (magit-section-parent diff)))
+    (unless (eq 'diff (magit-section-type diff))
+      (error "No diff at this location"))
+    (let* ((type (magit-diff-item-kind diff))
+           (file1 (magit-diff-item-file diff))
+           (file2 (magit-diff-item-file2 diff))
+           (range (magit-diff-item-range diff)))
+      (cond
+       ((memq type '(new deleted typechange))
+        (message "Why ediff a %s file?" type))
+       ((and (eq type 'unmerged)
+             (eq (cdr range) 'working))
+        (magit-interactive-resolve file1))
+       ((consp (car range))
+        (magit-ediff* (magit-show (caar range) file2)
+                      (magit-show (cdar range) file2)
+                      (magit-show (cdr range) file1)))
+       (t
+        (magit-ediff* (magit-show (car range) file2)
+                      (magit-show (cdr range) file1)))))))
+
+(defun magit-ediff* (a b &optional c)
+  (setq magit-ediff-buffers (list a b c))
+  (setq magit-ediff-windows (current-window-configuration))
+  (add-hook 'ediff-quit-hook 'magit-ediff-restore 'append)
+  (if c
+      (ediff-buffers3 a b c)
+    (ediff-buffers a b)))
+
+(defun magit-ediff-restore()
+  "Kill any buffers in `magit-ediff-buffers' that are not visiting files and
+restore the window state that was saved before ediff was called."
+  (dolist (buffer magit-ediff-buffers)
+    (if (and (null (buffer-file-name buffer))
+             (buffer-live-p buffer))
+        (kill-buffer buffer)))
+  (setq magit-ediff-buffers nil)
+  (set-window-configuration magit-ediff-windows)
+  (remove-hook 'ediff-quit-hook 'magit-ediff-restore))
+
+(defun magit-refresh-diff-buffer (range args)
+  (let ((magit-current-diff-range (cond
+                                   ((stringp range)
+                                    (cons range 'working))
+                                   ((null (cdr range))
+                                    (cons (car range) 'working))
+                                   (t
+                                    range))))
+    (setq magit-current-range range)
+    (magit-create-buffer-sections
+      (magit-git-section 'diffbuf
+                         (magit-rev-range-describe range "Changes")
+                         'magit-wash-diffs
+                         "diff" (magit-diff-U-arg) args "--"))))
+
+(define-derived-mode magit-diff-mode magit-mode "Magit Diff"
+  "Mode for looking at a git diff.
+
+\\{magit-diff-mode-map}"
+  :group 'magit)
+
+(magit-define-command diff (range)
+  (interactive (list (magit-read-rev-range "Diff")))
+  (if range
+      (let* ((dir default-directory)
+             (args (magit-rev-range-to-git range))
+             (buf (get-buffer-create "*magit-diff*")))
+        (display-buffer buf)
+        (with-current-buffer buf
+          (magit-mode-init dir 'magit-diff-mode #'magit-refresh-diff-buffer range args)))))
+
+(magit-define-command diff-working-tree (rev)
+  (interactive (list (magit-read-rev "Diff with" (magit-default-rev))))
+  (magit-diff (or rev "HEAD")))
+
+(defun magit-diff-with-mark ()
+  (interactive)
+  (magit-diff (cons (magit-marked-commit)
+                    (magit-commit-at-point))))
+
+;;; Wazzup
+
+(defvar magit-wazzup-head nil
+  "The integration head for the current wazzup buffer.
+This is only non-nil in wazzup buffers.")
+(make-variable-buffer-local 'magit-wazzup-head)
+
+(defvar magit-wazzup-all-p nil
+  "Non-nil if the current wazzup buffer displays excluded branches.
+This is only meaningful in wazzup buffers.")
+(make-variable-buffer-local 'magit-wazzup-all-p)
+
+(defun magit-wazzup-toggle-ignore (branch edit)
+  (let ((ignore-file (concat (magit-git-dir) "info/wazzup-exclude")))
+    (if edit
+        (setq branch (read-string "Branch to ignore for wazzup: " branch)))
+    (let ((ignored (magit-file-lines ignore-file)))
+      (cond ((member branch ignored)
+             (when (or (not edit)
+                       (y-or-n-p "Branch %s is already ignored.  Unignore? "))
+               (setq ignored (delete branch ignored))))
+            (t
+             (setq ignored (append ignored (list branch)))))
+      (magit-write-file-lines ignore-file ignored)
+      (magit-need-refresh))))
+
+(defun magit-refresh-wazzup-buffer (head all)
+  (setq magit-wazzup-head head)
+  (setq magit-wazzup-all-p all)
+  (let ((branch-desc (or head "(detached) HEAD")))
+    (unless head (setq head "HEAD"))
+    (magit-create-buffer-sections
+      (magit-with-section 'wazzupbuf nil
+        (insert (format "Wazzup, %s\n\n" branch-desc))
+        (let* ((excluded (magit-file-lines (concat (magit-git-dir) "info/wazzup-exclude")))
+               (all-branches (magit-list-interesting-refs))
+               (branches (if all all-branches
+                           (delq nil (mapcar
+                                      (lambda (b)
+                                        (and (not
+                                              (member (cdr b) excluded))
+                                             b))
+                                      all-branches))))
+               (reported (make-hash-table :test #'equal)))
+          (dolist (branch branches)
+            (let* ((name (car branch))
+                   (ref (cdr branch))
+                   (hash (magit-rev-parse ref))
+                   (reported-branch (gethash hash reported)))
+              (unless (or (and reported-branch
+                               (string= (file-name-nondirectory ref)
+                                        reported-branch))
+                          (not (magit-git-string "merge-base" head ref)))
+                (puthash hash (file-name-nondirectory ref) reported)
+                (let* ((n (length (magit-git-lines "log" "--pretty=oneline"
+                                                   (concat head ".." ref))))
+                       (section
+                        (let ((magit-section-hidden-default t))
+                          (magit-git-section
+                           (cons ref 'wazzup)
+                           (format "%s unmerged commits in %s%s"
+                                   n name
+                                   (if (member ref excluded)
+                                       " (normally ignored)"
+                                     ""))
+                           'magit-wash-log
+                           "log"
+                           (format "--max-count=%s" magit-log-cutoff-length)
+                           "--abbrev-commit"
+                           (format "--abbrev=%s" magit-sha1-abbrev-length)
+                           "--graph"
+                           "--pretty=oneline"
+                           (format "%s..%s" head ref)
+                           "--"))))
+                  (magit-set-section-info ref section))))))))))
+
+(define-derived-mode magit-wazzup-mode magit-mode "Magit Wazzup"
+  "Mode for looking at commits that could be merged from other branches.
+
+\\{magit-wazzup-mode-map}"
+  :group 'magit)
+
+(defun magit-wazzup (&optional all)
+  (interactive "P")
+  (let ((topdir (magit-get-top-dir default-directory))
+        (current-branch (magit-get-current-branch)))
+    (magit-buffer-switch "*magit-wazzup*")
+    (magit-mode-init topdir 'magit-wazzup-mode
+                     #'magit-refresh-wazzup-buffer
+                     current-branch all)))
+
+(defun magit-filename (filename)
+  "Return the path of FILENAME relative to its git repository.
+
+If FILENAME is absolute, return a path relative to the git
+repository containing it. Otherwise, return a path relative to
+the current git repository."
+  (let ((topdir (expand-file-name
+                 (magit-get-top-dir (or (file-name-directory filename)
+                                        default-directory))))
+        (file (file-truename filename)))
+    (when (and (not (string= topdir ""))
+               ;; FILE must start with the git repository path
+               (zerop (string-match-p (concat "\\`" topdir) file)))
+      (substring file (length topdir)))))
+
+;; This variable is used to keep track of the current file in the
+;; *magit-log* buffer when this one is dedicated to showing the log of
+;; just 1 file.
+(defvar magit-file-log-file nil)
+(make-variable-buffer-local 'magit-file-log-file)
+
+(defun magit-refresh-file-log-buffer (file range style)
+  "Refresh the current file-log buffer by calling git.
+
+FILE is the path of the file whose log must be displayed.
+
+`magit-current-range' will be set to the value of RANGE.
+
+STYLE controls the display. It is either `'long',  `'oneline', or something else.
+ "
+  (magit-configure-have-graph)
+  (magit-configure-have-decorate)
+  (magit-configure-have-abbrev)
+  (setq magit-current-range range)
+  (setq magit-file-log-file file)
+  (magit-create-log-buffer-sections
+    (apply #'magit-git-section nil
+           (magit-rev-range-describe range (format "Commits for file %s" file))
+           (apply-partially 'magit-wash-log style)
+           `("log"
+             ,(format "--max-count=%s" magit-log-cutoff-length)
+             ,"--abbrev-commit"
+             ,(format "--abbrev=%s" magit-sha1-abbrev-length)
+             ,@(cond ((eq style 'long) (list "--stat" "-z"))
+                     ((eq style 'oneline) (list "--pretty=oneline"))
+                     (t nil))
+             ,@(if magit-have-decorate (list "--decorate=full"))
+             ,@(if magit-have-graph (list "--graph"))
+             "--"
+             ,file))))
+
+(defun magit-file-log (&optional all)
+  "Display the log for the currently visited file or another one.
+
+With a prefix argument or if no file is currently visited, ask
+for the file whose log must be displayed."
+  (interactive "P")
+  (let ((topdir (magit-get-top-dir default-directory))
+        (current-file (magit-filename
+                       (if (or current-prefix-arg (not buffer-file-name))
+                           (magit-read-file-from-rev (magit-get-current-branch))
+                        buffer-file-name)))
+        (range "HEAD"))
+    (magit-buffer-switch "*magit-log*")
+    (magit-mode-init topdir 'magit-log-mode
+                     #'magit-refresh-file-log-buffer
+                     current-file range 'oneline)))
+
+(defun magit-show-file-revision ()
+  "Open a new buffer showing the current file in the revision at point."
+  (interactive)
+  (flet ((magit-show-file-from-diff (item)
+                                    (switch-to-buffer-other-window
+                                     (magit-show (cdr (magit-diff-item-range item))
+                                                 (magit-diff-item-file item)))))
+    (magit-section-action (item info "show")
+      ((commit)
+       (let ((current-file (or magit-file-log-file
+                               (magit-read-file-from-rev info))))
+         (switch-to-buffer-other-window
+          (magit-show info current-file))))
+      ((hunk) (magit-show-file-from-diff (magit-hunk-item-diff item)))
+      ((diff) (magit-show-file-from-diff item)))))
+
+;;; Miscellaneous
+
+(defun magit-ignore-modifiable-file (file edit)
+  "Prompt the user for the filename to be added to git ignore.
+\\<minibuffer-local-map>
+The minibuffer's future history (accessible with \\[next-history-element])
+contains predefined values (such as wildcards) that might
+be of interest.
+The history and default value are derived from the filename FILE.
+If EDIT argument is negative, the prompt proposes wildcard by default.
+"
+  (let* ((just-extension (concat "*." (file-name-extension file)))
+         (full-extension (concat (file-name-directory file) just-extension))
+         (just-file (file-name-nondirectory file))
+         ;; change the order in history depending on the negativity of
+         ;; EDIT.
+         (history (if (< (prefix-numeric-value edit) 0)
+                      (list full-extension just-extension file just-file)
+                    (list file full-extension just-extension just-file))))
+    (read-string
+     (format "File to ignore [%s]: " (car history))
+     nil nil history)))
+
+(defun magit-ignore-file (file edit local)
+  "Add FILE to the list of files to ignore.
+\\<minibuffer-local-map>
+If EDIT is non-`nil', prompt the user for the filename to
+be added to git ignore. In this case, the minibuffer's
+future history (accessible with \\[next-history-element]) contains predefined
+values (such as wildcards) that might be of interest.
+
+If LOCAL is nil, the `.gitignore' file is updated.
+Otherwise, it is `.git/info/exclude'."
+  (let* ((local-ignore-dir (concat (magit-git-dir) "info/"))
+         (ignore-file (if local
+                          (concat local-ignore-dir "exclude")
+                        ".gitignore")))
+    (if edit
+      (setq file (magit-ignore-modifiable-file file edit)))
+    (if (and local (not (file-exists-p local-ignore-dir)))
+        (make-directory local-ignore-dir t))
+    (with-temp-buffer
+      (when (file-exists-p ignore-file)
+        (insert-file-contents ignore-file))
+      (goto-char (point-max))
+      (unless (bolp)
+        (insert "\n"))
+      (insert file "\n")
+      (write-region nil nil ignore-file))
+    (magit-need-refresh)))
+
+(defun magit-ignore-item ()
+  "Add FILE to the `.gitignore' list of files to ignore.
+\\<minibuffer-local-map>
+With a prefix argument, prompt the user for the filename to
+be added. In this case, the minibuffer's future history
+\(accessible with \\[next-history-element]) contains predefined values (such as
+wildcards) that might be of interest. If prefix argument is
+negative, the prompt proposes wildcard by default."
+  (interactive)
+  (magit-section-action (item info "ignore")
+    ((untracked file)
+     (magit-ignore-file (concat "/" info) current-prefix-arg nil))
+    ((wazzup)
+     (magit-wazzup-toggle-ignore info current-prefix-arg))))
+
+(defun magit-ignore-item-locally ()
+  "Add FILE to the `.git/info/exclude' list of files to ignore.
+\\<minibuffer-local-map>
+With a prefix argument, prompt the user for the filename to
+be added. In this case, the minibuffer's future history
+(accessible with \\[next-history-element]) contains predefined values (such as
+wildcards) that might be of interest. If prefix argument is
+negative, the prompt proposes wildcard by default."
+  (interactive)
+  (magit-section-action (item info "ignore")
+    ((untracked file)
+     (magit-ignore-file (concat "/" info) current-prefix-arg t))))
+
+(defun magit-discard-diff (diff stagedp)
+  (let ((kind (magit-diff-item-kind diff))
+        (file (magit-diff-item-file diff)))
+    (cond ((eq kind 'deleted)
+           (when (yes-or-no-p (format "Resurrect %s? " file))
+             (magit-run-git "reset" "-q" "--" file)
+             (magit-run-git "checkout" "--" file)))
+          ((eq kind 'new)
+           (if (yes-or-no-p (format "Delete %s? " file))
+               (magit-run-git "rm" "-f" "--" file)))
+          (t
+           (if (yes-or-no-p (format "Discard changes to %s? " file))
+               (if stagedp
+                   (magit-run-git "checkout" "HEAD" "--" file)
+                 (magit-run-git "checkout" "--" file)))))))
+
+(defun magit-discard-item ()
+  (interactive)
+  (magit-section-action (item info "discard")
+    ((untracked file)
+     (when (yes-or-no-p (format "Delete %s? " info))
+       (if (and (file-directory-p info)
+                (not (file-symlink-p info)))
+           (magit-delete-directory info 'recursive)
+         (delete-file info))
+       (magit-refresh-buffer)))
+    ((untracked)
+     (if (yes-or-no-p "Delete all untracked files and directories? ")
+         (magit-run-git "clean" "-df")))
+    ((unstaged diff hunk)
+     (when (yes-or-no-p (if (magit-use-region-p)
+                            "Discard changes in region? "
+                          "Discard hunk? "))
+       (magit-apply-hunk-item-reverse item)))
+    ((staged diff hunk)
+     (if (magit-file-uptodate-p (magit-diff-item-file
+                                 (magit-hunk-item-diff item)))
+         (when (yes-or-no-p (if (magit-use-region-p)
+                                "Discard changes in region? "
+                              "Discard hunk? "))
+           (magit-apply-hunk-item-reverse item "--index"))
+       (error "Can't discard this hunk.  Please unstage it first")))
+    ((unstaged diff)
+     (magit-discard-diff item nil))
+    ((staged diff)
+     (if (magit-file-uptodate-p (magit-diff-item-file item))
+         (magit-discard-diff item t)
+       (error "Can't discard staged changes to this file.  Please unstage it first")))
+    ((diff diff)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-discard-item)))
+    ((diff diff hunk)
+     (save-excursion
+       (magit-goto-parent-section)
+       (magit-goto-parent-section)
+       (magit-discard-item)))
+    ((hunk)
+     (error "Can't discard this hunk"))
+    ((diff)
+     (error "Can't discard this diff"))
+    ((stash)
+     (when (yes-or-no-p "Discard stash? ")
+       (magit-run-git "stash" "drop" info)))
+    ((branch)
+     (when (yes-or-no-p (if current-prefix-arg
+                            "Force delete branch?"
+                          "Delete branch? "))
+       (magit-delete-branch info current-prefix-arg)))
+    ((remote)
+     (when (yes-or-no-p "Remove remote? ")
+       (magit-remove-remote info)))))
+
+(defun magit-move-item ()
+  (interactive)
+  (magit-section-action (item info "move")
+    ((branch)
+     (call-interactively 'magit-move-branch))
+    ((remote)
+     (call-interactively 'magit-rename-remote))))
+
+(defmacro magit-visiting-file-item (&rest body)
+  `(let ((marker (save-window-excursion
+                   (magit-visit-file-item)
+                   (set-marker (make-marker) (point)))))
+     (save-excursion
+       (with-current-buffer (marker-buffer marker)
+         (goto-char marker)
+         ,@body))))
+
+(defun magit-add-change-log-entry-no-option (&optional other-window)
+  "Add a change log entry for current change.
+With a prefix argument, edit in other window.
+The name of the change log file is set by variable change-log-default-name."
+  (interactive "P")
+  (if other-window
+      (magit-visiting-file-item (add-change-log-entry-other-window))
+    (magit-visiting-file-item (add-change-log-entry))))
+
+(defun magit-add-change-log-entry-other-window ()
+  (interactive)
+  (magit-visiting-file-item (call-interactively 'add-change-log-entry-other-window)))
+
+(eval-after-load 'dired-x
+  '(defun magit-dired-jump (&optional other-window)
+    "Visit current item.
+With a prefix argument, visit in other window."
+    (interactive "P")
+    (require 'dired-x)
+    (magit-section-action (item info "dired-jump")
+      ((untracked file)
+       (dired-jump other-window (file-truename info)))
+      ((diff)
+       (dired-jump other-window (file-truename (magit-diff-item-file item))))
+      ((hunk)
+       (dired-jump other-window
+                   (file-truename (magit-diff-item-file
+                                   (magit-hunk-item-diff item))))))))
+
+(defun magit-visit-file-item (&optional other-window)
+  "Visit current file associated with item.
+With a prefix argument, visit in other window."
+  (interactive "P")
+  (magit-section-action (item info "visit-file")
+    ((untracked file)
+     (funcall
+      (if other-window 'find-file-other-window 'find-file)
+      info))
+    ((diff)
+     (let ((file (magit-diff-item-file item)))
+       (cond ((not (file-exists-p file))
+              (error "Can't visit deleted file: %s" file))
+             ((file-directory-p file)
+              (magit-status file))
+             (t
+              (funcall
+               (if other-window 'find-file-other-window 'find-file)
+               file)))))
+    ((hunk)
+     (let ((file (magit-diff-item-file (magit-hunk-item-diff item)))
+           (line (magit-hunk-item-target-line item)))
+       (if (not (file-exists-p file))
+           (error "Can't visit deleted file: %s" file))
+       (funcall
+        (if other-window 'find-file-other-window 'find-file)
+        file)
+       (goto-char (point-min))
+       (forward-line (1- line))))))
+
+(defun magit-visit-item (&optional other-window)
+  "Visit current item.
+With a prefix argument, visit in other window."
+  (interactive "P")
+  (magit-section-action (item info "visit")
+    ((untracked file)
+     (call-interactively 'magit-visit-file-item))
+    ((diff)
+     (call-interactively 'magit-visit-file-item))
+    ((hunk)
+     (call-interactively 'magit-visit-file-item))
+    ((commit)
+     (magit-show-commit info nil nil 'select))
+    ((stash)
+     (magit-show-stash info)
+     (pop-to-buffer magit-stash-buffer-name))
+    ((branch)
+     (magit-checkout info))
+    ((longer)
+     (magit-log-show-more-entries ()))))
+
+(defun magit-show-item-or-scroll-up ()
+  (interactive)
+  (magit-section-action (item info)
+    ((commit)
+     (magit-show-commit info #'scroll-up))
+    ((stash)
+     (magit-show-stash info #'scroll-up))
+    (t
+     (scroll-up))))
+
+(defun magit-show-item-or-scroll-down ()
+  (interactive)
+  (magit-section-action (item info)
+    ((commit)
+     (magit-show-commit info #'scroll-down))
+    ((stash)
+     (magit-show-stash info #'scroll-down))
+    (t
+     (scroll-down))))
+
+(defun magit-mark-item (&optional unmark)
+  (interactive "P")
+  (if unmark
+      (magit-set-marked-commit nil)
+    (magit-section-action (item info "mark")
+      ((commit)
+       (magit-set-marked-commit (if (eq magit-marked-commit info)
+                                    nil
+                                  info))))))
+
+(defun magit-describe-item ()
+  (interactive)
+  (let ((section (magit-current-section)))
+    (message "Section: %s %s-%s %S %S %S"
+             (magit-section-type section)
+             (magit-section-beginning section)
+             (magit-section-end section)
+             (magit-section-title section)
+             (magit-section-info section)
+             (magit-section-context-type section))))
+
+(defun magit-copy-item-as-kill ()
+  "Copy sha1 of commit at point into kill ring."
+  (interactive)
+  (magit-section-action (item info "copy")
+    ((commit)
+     (kill-new info)
+     (message "%s" info))))
+
+(eval-when-compile (require 'server))
+
+(defun magit-server-running-p ()
+  "Test whether server is running (works with < 23 as well).
+
+Return values:
+  nil              the server is definitely not running.
+  t                the server seems to be running.
+  something else   we cannot determine whether it's running without using
+                   commands which may have to wait for a long time."
+  (require 'server)
+  (if (functionp 'server-running-p)
+      (server-running-p)
+    (condition-case nil
+        (if server-use-tcp
+            (with-temp-buffer
+              (insert-file-contents-literally (expand-file-name server-name server-auth-dir))
+              (or (and (looking-at "127\\.0\\.0\\.1:[0-9]+ \\([0-9]+\\)")
+                       (assq 'comm
+                             (process-attributes
+                              (string-to-number (match-string 1))))
+                       t)
+                  :other))
+          (delete-process
+           (make-network-process
+            :name "server-client-test" :family 'local :server nil :noquery t
+            :service (expand-file-name server-name server-socket-dir)))
+          t)
+      (file-error nil))))
+
+(defun magit-interactive-rebase ()
+  "Start a git rebase -i session, old school-style."
+  (interactive)
+  (unless (magit-server-running-p)
+    (server-start))
+  (let* ((section (get-text-property (point) 'magit-section))
+         (commit (and (member 'commit (magit-section-context-type section))
+                      (magit-section-info section)))
+         (old-editor (getenv "GIT_EDITOR")))
+    (setenv "GIT_EDITOR" (concat (locate-file "emacsclient" exec-path)
+                                 " -s " server-name))
+    (unwind-protect
+        (magit-run-git-async "rebase" "-i"
+                             (or (and commit (concat commit "^"))
+                                 (magit-read-rev "Interactively rebase to" (magit-guess-branch))))
+      (if old-editor
+          (setenv "GIT_EDITOR" old-editor)))))
+
+(define-derived-mode magit-branch-manager-mode magit-mode "Magit Branch"
+  "Magit Branches")
+
+(defun magit-quit-window (&optional kill-buffer)
+  "Bury the buffer and delete its window.  With a prefix argument, kill the
+buffer instead."
+  (interactive "P")
+  (quit-window kill-buffer (selected-window)))
+
+(defun magit--branch-name-at-point ()
+  "Get the branch name in the line at point."
+  (let ((branch (magit-section-info (magit-current-section))))
+    (or branch (error "No branch at point"))))
+
+(defun magit--branches-for-remote-repo (remote)
+  "Return a list of remote branch names for REMOTE.
+These are the branch names with the remote name stripped."
+  (remq nil
+        (mapcar (lambda (line)
+                  (save-match-data
+                    (if (and (not (string-match-p " -> " line))
+                             (string-match (concat "^ +" remote "/\\([^ $]+\\)")
+                                           line))
+                        (match-string 1 line))))
+                (magit-git-lines "branch" "-r"))))
+
+(defvar magit-branches-buffer-name "*magit-branches*")
+
+(defun magit--is-branch-at-point-remote ()
+  "Return non-nil if the branch at point is a remote tracking branch"
+  (magit-remote-part-of-branch (magit--branch-name-at-point)))
+
+(defun magit-remote-part-of-branch (branch)
+  (when (string-match-p "^\\(?:refs/\\)?remotes\\/" branch)
+    (loop for remote in (magit-git-lines "remote")
+          when (string-match-p (format "^\\(?:refs/\\)?remotes\\/%s\\/" (regexp-quote remote)) branch) return remote)))
+
+(defun magit-branch-no-remote (branch)
+  (let ((remote (magit-remote-part-of-branch branch)))
+    (if remote
+        (progn
+          ;; This has to match if remote is non-nil
+          (assert (string-match (format "^\\(?:refs/\\)?remotes\\/%s\\/\\(.*\\)" (regexp-quote remote)) branch)
+                  'show-args "Unexpected string-match failure: %s %s")
+          (match-string 1 branch))
+      branch)))
+
+(defun magit-wash-branch-line (&optional remote-name)
+  (looking-at (concat
+               "^\\([ *] \\)"                 ; 1: current branch marker
+               "\\(.+?\\) +"                  ; 2: branch name
+
+               "\\(?:"
+
+               "\\([0-9a-fA-F]+\\)"           ; 3: sha1
+               " "
+               "\\(?:\\["
+               "\\([^:\n]+?\\)"               ; 4: tracking (non-greedy + to avoid matching \n)
+               "\\(?:: \\)?"
+               "\\(?:ahead \\([0-9]+\\)\\)?"  ; 5: ahead
+               "\\(?:, \\)?"
+               "\\(?:behind \\([0-9]+\\)\\)?" ; 6: behind
+               "\\] \\)?"
+               "\\(?:.*\\)"                   ; message
+
+               "\\|"                          ; or
+
+               "-> "                          ; the pointer to
+               "\\(.+\\)"                     ; 7: a ref
+
+               "\\)\n"))
+
+  (let* ((current-string (match-string 1))
+         (branch         (match-string 2))
+         (sha1           (match-string 3))
+         (tracking       (match-string 4))
+         (ahead          (match-string 5))
+         (behind         (match-string 6))
+         (other-ref      (match-string 7))
+         (current (string-match-p "^\\*" current-string)))
+
+    ; the current line is deleted before being reconstructed
+    (delete-region (point)
+                   (line-beginning-position 2))
+
+    (magit-with-section branch 'branch
+      (magit-set-section-info branch)
+      (insert-before-markers
+       ; sha1
+       (propertize (or sha1
+                       (make-string magit-sha1-abbrev-length ? ))
+                   'face 'magit-log-sha1)
+       " "
+       ; current marker
+       (if current
+           "# "
+         "  ")
+       ; branch name
+       (apply 'propertize (magit-branch-no-remote branch)
+              (if current
+                  '(face magit-branch)))
+       ; other ref that this branch is pointing to
+       (if other-ref
+           (concat " -> " (substring other-ref (+ 1 (length remote-name))))
+         "")
+       ; tracking information
+       (if (and tracking
+                (equal (magit-remote-branch-for branch t)
+                       (concat "refs/remotes/" tracking)))
+           (concat " ["
+                   ; getting rid of the tracking branch name if it is the same as the branch name
+                   (let* ((tracking-remote (magit-get "branch" branch "remote"))
+                          (tracking-branch (substring tracking (+ 1 (length tracking-remote)))))
+                     (propertize (if (string= branch tracking-branch)
+                                     (concat "@ " tracking-remote)
+                                   (concat tracking-branch " @ " tracking-remote))
+                                 'face 'magit-log-head-label-remote))
+                   ; ahead/behind information
+                   (if (or ahead
+                           behind)
+                       ": "
+                     "")
+                   (if ahead
+                       (concat "ahead "
+                               (propertize ahead
+                                           'face (if current
+                                                     'magit-branch))
+                               (if behind
+                                   ", "
+                                 ""))
+                     "")
+                   (if behind
+                       (concat "behind "
+                               (propertize behind
+                                           'face 'magit-log-head-label-remote))
+                     "")
+                   "]")
+         "")
+       "\n"))))
+
+(defun magit-wash-remote-branches-group (group)
+  (let* ((remote-name (first group))
+         (url (magit-get "remote" remote-name "url"))
+         (push-url (magit-get "remote" remote-name "pushurl"))
+         (urls (concat url (if push-url
+                               (concat ", "push-url)
+                             "")))
+         (marker (second group)))
+
+    (magit-with-section (concat "remote:" remote-name) 'remote
+      (magit-set-section-info remote-name)
+      (insert-before-markers (propertize (format "%s (%s):" remote-name urls) 'face 'magit-section-title) "\n")
+      (magit-wash-branches-between-point-and-marker marker remote-name))
+    (insert-before-markers "\n")))
+
+(defun magit-wash-branches-between-point-and-marker (marker &optional remote-name)
+  (save-restriction
+    (narrow-to-region (point) marker)
+    (magit-wash-sequence
+     (if remote-name
+         (apply-partially 'magit-wash-branch-line remote-name)
+       #'magit-wash-branch-line))))
+
+(defun magit-wash-branches ()
+         ; get the names of the remotes
+  (let* ((remotes (magit-git-lines "remote"))
+         ; get the location of remotes in the buffer
+         (markers
+          (append (mapcar (lambda (remote)
+                            (save-excursion
+                              (when (search-forward-regexp
+                                     (concat "^  remotes\\/" remote) nil t)
+                                (beginning-of-line)
+                                (point-marker))))
+                          remotes)
+                  (list (save-excursion
+                          (goto-char (point-max))
+                          (point-marker)))))
+         ; list of remote elements to display in the buffer
+         (remote-groups (loop for remote in remotes
+                              for end-markers on (cdr markers)
+                              for marker = (loop for x in end-markers thereis x)
+                              collect (list remote marker))))
+
+    ; actual displaying of information
+    (magit-with-section "local" nil
+      (insert-before-markers (propertize "Local:" 'face 'magit-section-title) "\n")
+      (magit-set-section-info ".")
+      (magit-wash-branches-between-point-and-marker
+       (loop for x in markers thereis x)))
+
+    (insert-before-markers "\n")
+
+    (mapc 'magit-wash-remote-branches-group remote-groups)
+
+    ; make sure markers point to nil so that they can be garbage collected
+    (mapc (lambda (marker)
+            (when marker
+             (set-marker marker nil)))
+          markers)))
+
+(defun magit-refresh-branch-manager ()
+  (magit-create-buffer-sections
+    (magit-git-section "branches" nil 'magit-wash-branches
+                       "branch"
+                       "-vva"
+                       (format "--abbrev=%s" magit-sha1-abbrev-length))))
+
+(magit-define-command branch-manager ()
+  (interactive)
+  (let ((topdir (magit-get-top-dir default-directory)))
+    (magit-buffer-switch magit-branches-buffer-name)
+    (magit-mode-init topdir 'magit-branch-manager-mode #'magit-refresh-branch-manager)))
+
+(defun magit-change-what-branch-tracks ()
+  "Change which remote branch the current branch tracks."
+  (interactive)
+  (if (magit--is-branch-at-point-remote)
+      (error "Cannot modify a remote branch"))
+  (let* ((local-branch (magit--branch-name-at-point))
+         (new-tracked (magit-read-rev  "Change tracked branch to"
+                                       nil
+                                       (lambda (ref)
+                                         (not (string-match-p "refs/remotes/"
+                                                              ref)))))
+         new-remote new-branch)
+    (unless (string= (or new-tracked "") "")
+      (cond (;; Match refs that are unknown in the local repository if
+             ;; `magit-remote-ref-format' is set to
+             ;; `name-then-remote'. Can be useful if you want to
+             ;; create a new branch in a remote repository.
+             (string-match "^\\([^ ]+\\) +(\\(.+\\))$" ; 1: branch name; 2: remote name
+                           new-tracked)
+             (setq new-remote (match-string 2 new-tracked)
+                   new-branch (concat "refs/heads/" (match-string 1 new-tracked))))
+            ((string-match "^\\(?:refs/remotes/\\)?\\([^/]+\\)/\\(.+\\)" ; 1: remote name; 2: branch name
+                           new-tracked)
+             (setq new-remote (match-string 1 new-tracked)
+                   new-branch (concat "refs/heads/" (match-string 2 new-tracked))))
+            (t (error "Cannot parse the remote and branch name"))))
+    (magit-set new-remote "branch" local-branch "remote")
+    (magit-set new-branch "branch" local-branch "merge")
+    (magit-branch-manager)
+    (if (string= (magit-get-current-branch) local-branch)
+        (magit-refresh-buffer (magit-find-status-buffer default-directory)))))
+
+(defvar magit-ediff-file)
+
+(defun magit-interactive-resolve (file)
+  (require 'ediff)
+  (let ((merge-status (magit-git-string "ls-files" "-u" "--" file))
+        (base-buffer (generate-new-buffer (concat file ".base")))
+        (our-buffer (generate-new-buffer (concat file ".current")))
+        (their-buffer (generate-new-buffer (concat file ".merged")))
+        (windows (current-window-configuration)))
+    (if (null merge-status)
+        (error "Cannot resolve %s" file))
+    (with-current-buffer base-buffer
+      (if (string-match "^[0-9]+ [0-9a-f]+ 1" merge-status)
+          (insert (magit-git-output `("cat-file" "blob" ,(concat ":1:" file))))))
+    (with-current-buffer our-buffer
+      (if (string-match "^[0-9]+ [0-9a-f]+ 2" merge-status)
+          (insert (magit-git-output `("cat-file" "blob" ,(concat ":2:" file)))))
+      (let ((buffer-file-name file))
+        (normal-mode)))
+    (with-current-buffer their-buffer
+      (if (string-match "^[0-9]+ [0-9a-f]+ 3" merge-status)
+          (insert (magit-git-output `("cat-file" "blob" ,(concat ":3:" file)))))
+      (let ((buffer-file-name file))
+        (normal-mode)))
+    ;; We have now created the 3 buffer with ours, theirs and the ancestor files
+    (with-current-buffer (ediff-merge-buffers-with-ancestor our-buffer their-buffer base-buffer)
+      (make-local-variable 'magit-ediff-file)
+      (setq magit-ediff-file file)
+      (make-local-variable 'magit-ediff-windows)
+      (setq magit-ediff-windows windows)
+      (make-local-variable 'ediff-quit-hook)
+      (add-hook 'ediff-quit-hook
+                (lambda ()
+                  (let ((buffer-A ediff-buffer-A)
+                        (buffer-B ediff-buffer-B)
+                        (buffer-C ediff-buffer-C)
+                        (buffer-Ancestor ediff-ancestor-buffer)
+                        (file magit-ediff-file)
+                        (file-buffer)
+                        (windows magit-ediff-windows))
+                    (ediff-cleanup-mess)
+                    (find-file file)
+                    (setq file-buffer (current-buffer))
+                    (erase-buffer)
+                    (insert-buffer-substring buffer-C)
+                    (kill-buffer buffer-A)
+                    (kill-buffer buffer-B)
+                    (kill-buffer buffer-C)
+                    (when (bufferp buffer-Ancestor) (kill-buffer buffer-Ancestor))
+                    (set-window-configuration windows)
+                    (magit-save-some-buffers
+                     "Conflict resolution finished; you may save the buffer"
+                     (lambda () (eq (current-buffer) file-buffer)))))))))
+
+(defun magit-interactive-resolve-item ()
+  (interactive)
+  (magit-section-action (item info "resolv")
+    ((diff)
+     (magit-interactive-resolve (cadr info)))))
+
+(defun magit-submodule-update (&optional init)
+  "Update the submodule of the current git repository
+
+With a prefix arg, do a submodule update --init"
+  (interactive "P")
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (apply #'magit-run-git-async "submodule" "update" (if init '("--init") ()))))
+
+(defun magit-submodule-update-init ()
+  "Update and init the submodule of the current git repository."
+  (interactive)
+  (magit-submodule-update t))
+
+(defun magit-submodule-init ()
+  "Initialize the submodules"
+  (interactive)
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (magit-run-git-async "submodule" "init")))
+
+(defun magit-submodule-sync ()
+  "Synchronizes submodules' remote URL configuration"
+  (interactive)
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (magit-run-git-async "submodule" "sync")))
+
+(defun magit-run-git-gui ()
+  "Run `git gui' for the current git repository"
+  (interactive)
+  (let* ((default-directory (magit-get-top-dir default-directory)))
+    (magit-start-process "Git Gui" nil magit-git-executable "gui")))
+
+(defun magit-run-gitk ()
+  "Run `gitk --all' for the current git repository"
+  (interactive)
+  (let ((default-directory (magit-get-top-dir default-directory)))
+    (cond
+     ((eq system-type 'windows-nt)
+      ;; Gitk is a shell script, and Windows doesn't know how to
+      ;; "execute" it.  The Windows version of Git comes with an
+      ;; implementation of "sh" and everything else it needs, but
+      ;; Windows users might not have added the directory where it's
+      ;; installed to their path
+      (let ((git-bin-dir (file-name-directory magit-gitk-executable))
+            (exec-path exec-path)
+            (process-environment process-environment))
+        (when git-bin-dir
+          ;; Adding it onto the end so that anything the user
+          ;; specified will get tried first.  Emacs looks in
+          ;; exec-path; PATH is the environment variable inherited by
+          ;; the process.  I need to change both.
+          (setq exec-path (append exec-path (list git-bin-dir)))
+          (push (format "PATH=%s;%s"
+                        (getenv "PATH")
+                        (replace-regexp-in-string "/" "\\\\" git-bin-dir))
+                process-environment))
+        (magit-start-process "Gitk" nil "sh" magit-gitk-executable "--all")))
+     (t
+      (magit-start-process "Gitk" nil magit-gitk-executable "--all")))))
+
+(defun magit-load-config-extensions ()
+  "Try to load magit extensions that are defined at git config
+layer. This can be added to `magit-mode-hook' for example"
+  (dolist (ext (magit-get-all "magit.extension"))
+    (let ((sym (intern (format "magit-%s-mode" ext))))
+      (when (and (fboundp sym)
+                 (not (eq sym 'magit-wip-save-mode)))
+        (funcall sym 1)))))
+
+(provide 'magit)
+
+;; rest of magit core
+(require 'magit-key-mode)
+(require 'magit-bisect)
+
+;;; magit.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/magit.elc b/.emacs.d/elpa/magit-1.2.0/magit.elc
new file mode 100644
index 0000000..2805f5c
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/magit.elc differ
diff --git a/.emacs.d/elpa/magit-1.2.0/magit.info b/.emacs.d/elpa/magit-1.2.0/magit.info
new file mode 100644
index 0000000..deda92f
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/magit.info
@@ -0,0 +1,1359 @@
+This is magit.info, produced by makeinfo version 4.8 from magit.texi.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Magit: (magit).        Using Git from Emacs with Magit.
+END-INFO-DIR-ENTRY
+
+   Copyright (C) 2008, 2009, 2010, 2011 Magit contributors. (See the
+header of magit.el for the lengthy list of Magit contributors.)
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU Free Documentation License,
+     Version 1.2 or any later version published by the Free Software
+     Foundation; with no Invariant Sections, with no Front-Cover Texts,
+     and with no Back-Cover Texts.
+
+
+File: magit.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Magit User Manual
+*****************
+
+Magit is an interface to the version control system Git, implemented as
+an extension to Emacs.  Magit supports GNU Emacs version 22 or later.
+It may work with other emacsen, but Magit developers do not intend to
+investigate and fix bugs that only appear in unsupported versions.
+Patches to fix bugs in other emacsen or volunteers to maintain
+compatibility are still welcome.
+
+* Menu:
+
+* Introduction::
+* Acknowledgments::
+* Sections::
+* Status::
+* Untracked files::
+* Staging and Committing::
+* History::
+* Reflogs::
+* Commit Buffer::
+* Diffing::
+* Tagging::
+* Resetting::
+* Stashing::
+* Branching::
+* The Branch Manager::
+* Wazzup::
+* Merging::
+* Rebasing::
+* Interactive Rebasing::
+* Rewriting::
+* Pushing and Pulling::
+* Bisecting::
+* Submodules::
+* Using Magit Extensions::
+* Using Git Directly::
+* Customization::
+* Frequently Asked Questions::
+
+
+File: magit.info,  Node: Introduction,  Next: Acknowledgments,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+With Magit, you can inspect and modify your Git repositories with
+Emacs.  You can review and commit the changes you have made to the
+tracked files, for example, and you can browse the history of past
+changes.  There is support for cherry picking, reverting, merging,
+rebasing, and other common Git operations.
+
+   Magit is not a complete interface to Git; it just aims to make the
+most common Git operations convenient.  Thus, Magit will likely not
+save you from learning Git itself.
+
+   This manual provides a tour of all Magit features.  It does not give
+an introduction to version control in general, or to Git in particular.
+
+   The main entry point to Magit is `M-x magit-status', which will put
+you in Magit's status buffer.  You will be using it frequently, so it
+is probably a good idea to bind `magit-status' to a key of your choice.
+
+   In addition to the status buffer, Magit will also create buffers that
+show lists of commits, buffers with diffs, and other kinds of buffers.
+All these buffers are in `magit-mode' and have the same key bindings.
+Not all commands make sense in all contexts, but a given key will
+always do the same thing in all Magit buffers.
+
+   Naturally, Magit runs the `git' command to do most of the work.  The
+`*magit-process*' buffer contains the transcript of the most recent
+command.  You can switch to it with `$'.
+
+
+File: magit.info,  Node: Acknowledgments,  Next: Sections,  Prev: Introduction,  Up: Top
+
+2 Acknowledgments
+*****************
+
+Marius Vollmer started the whole project.  Thanks !
+
+   From day one of the first Magit announcement, John Wiegley has
+contributed numerous fixes, UI improvements, and new features.  Thanks!
+
+   Linh Dang and Christian Neukirchen also contributed from day one.
+Thanks!
+
+   Phil Hagelberg joined a few days later.  Thanks!
+
+   Alex Ott contributed support for git svn.  Thanks!
+
+   Marcin Bachry contributed bug fixes and support for decorated logs.
+Thanks!
+
+   Alexey Voinov fixed bugs.  Thanks!
+
+   Rémi Vanicat helped with Tramp support.  Thanks!
+
+
+File: magit.info,  Node: Sections,  Next: Status,  Prev: Acknowledgments,  Up: Top
+
+3 Sections
+**********
+
+All Magit buffers are structured into nested 'sections'.  These
+sections can be hidden and shown individually.  When a section is
+hidden, only its first line is shown and all its children are
+completely invisible.
+
+   The most fine-grained way to control the visibility of sections is
+the `TAB' key.  It will to toggle the current section (the section that
+contains point) between being hidden and being shown.
+
+   Typing `S-TAB' toggles the visibility of the children of the current
+section.  When all of them are shown, they will all be hidden.
+Otherwise, when some or all are hidden, they will all be shown.
+
+   The digit keys `1', `2', `3', and `4' control the visibility of
+sections based on levels.  Hitting `2', for example, will show sections
+on levels one and two, and will hide sections on level 3.  However,
+only sections that are a parent or child of the current section are
+affected.
+
+   For example, when the current section is on level 3 and you hit `1',
+the grand-parent of the current section (which is on level one) will be
+shown, and the parent of the current section (level 2) will be hidden.
+The visibility of no other section will be changed.
+
+   This sounds a bit complicated, but you'll figure it out.
+
+   Using `M-1', `M-2', `M-3', and `M-4' is similar to the unmodified
+digits, but now all sections on the respective level are affected,
+regardless of whether or not they are related to the current section.
+
+   For example, `M-1' will only show the first lines of the top-level
+sections and will hide everything else.  Typing `M-4' on the other hand
+will show everything.
+
+   Because of the way the status buffer is set up, some changes to
+section visibility are more common than others.  Files are on level 2
+and diff hunks are on level 4.  Thus, you can type `2' to collapse the
+diff of the current file, and `M-2' to collapse all files.  This
+returns the status buffer to its default setup and is a quick way to
+unclutter it after drilling down into the modified files.
+
+   Because `2' and `M-2' are so common in the status buffer, they are
+bound to additional, more mnemonic keys: `M-h' (hide) and `M-H' (hide
+all).  Likewise `4' and `M-4' are also available as `M-s' (show) and
+`M-S' (show all).
+
+   In other buffers than the status buffer, `M-h', `M-H', `M-s', and
+`M-S' might work on different levels than on 2 and 4, but they keep
+their general meaning: `M-H' hides all detail, and `M-S' shows
+everything.
+
+
+File: magit.info,  Node: Status,  Next: Untracked files,  Prev: Sections,  Up: Top
+
+4 Status
+********
+
+Running `M-x magit-status' displays the main interface of Magit, the
+status buffer.  You can have multiple status buffers active at the same
+time, each associated with its own Git repository.
+
+   When invoking `M-x magit-status' from within a Git repository, it
+will switch to the status buffer of that repository.  Otherwise, it
+will prompt for a directory.  With a prefix argument, it will always
+prompt.
+
+   You can set `magit-repo-dirs' to customize how `magit-status' asks
+for the repository to work on.  When `magit-repo-dirs' is nil,
+`magit-status' will simply ask for a directory.
+
+   If you specify a directory that is not a Git repository, `M-x
+magit-status' will offer to initialize it as one.
+
+   When `magit-repo-dirs' is not nil, it is treated as a list of
+directory names, and `magit-status' will find all Git repositories in
+those directories and offer them for completion.  (Magit will only look
+`magit-repo-dirs-depth' levels deep, however.)
+
+   With two prefix arguments, `magit-status' will always prompt for a
+raw directory.
+
+   Thus, you would normally set `magit-repo-dirs' to the places where
+you keep most of your Git repositories and switch between them with
+`C-u M-x magit-status'.  If you want to go to a repository outside of
+your normal working areas, or if you want to create a new repository,
+you would use `C-u C-u M-x magit-status'.
+
+   You need to explicitly refresh the status buffer when you have made
+changes to the repository from outside of Emacs.  You can type `g' in
+the status buffer itself, or just use `M-x magit-status' instead of
+`C-x b' when switching to it.  You also need to refresh the status
+buffer in this way after saving a file in Emacs.
+
+   The header at the top of the status buffer shows a short summary of
+the repository state: where it is located, which branch is checked out,
+etc.  Below the header are a number of sections that show details about
+the working tree and the staging area.  You can hide and show them as
+described in the previous section.
+
+   The first section shows _Untracked files_, if there are any.  See
+*Note Untracked files:: for more details.
+
+   The next two sections show your local changes.  They are explained
+fully in the next chapter, *Note Staging and Committing::.
+
+   If the current branch is associated with a remote tracking branch,
+the status buffer shows the differences between the current branch and
+the tracking branch.  See *Note Pushing and Pulling:: for more
+information.
+
+   During a history rewriting session, the status buffer shows the
+_Pending changes_ and _Pending commits_ sections.  See *Note
+Rewriting:: for more details.
+
+
+File: magit.info,  Node: Untracked files,  Next: Staging and Committing,  Prev: Status,  Up: Top
+
+5 Untracked files
+*****************
+
+Untracked files are shown in the _Untracked files_ section.
+
+   You can add an untracked file to the staging area with `s'.  If
+point is on the _Untracked files_ section title when you hit `s', all
+untracked files are staged.
+
+   Typing `C-u S' anywhere will also stage all untracked files,
+together with all changes to the tracked files.
+
+   You can instruct Git to ignore them by typing `i'.  This will add
+the filename to the `.gitignore' file.  Typing `C-u i' will ask you for
+the name of the file to ignore.  This is useful to ignore whole
+directories, for example.  In this case, the minibuffer's future history
+(accessible with `M-n') contains predefined values (such as wildcards)
+that might be of interest. If prefix argument is negative (for example
+after typing `C-- i'), the prompt proposes wildcard by default.  The
+`I' command is similar to `i' but will add the file to
+`.git/info/exclude' instead.
+
+   To delete an untracked file forever, use `k'.  If point is on the
+_Untracked files_ section title when you hit `k', all untracked files
+are deleted.
+
+
+File: magit.info,  Node: Staging and Committing,  Next: History,  Prev: Untracked files,  Up: Top
+
+6 Staging and Committing
+************************
+
+Comitting with Git is a two step process: first you add the changes you
+want to commit to a 'staging area', and then you commit them to the
+repository.  This allows you to only commit a subset of your local
+changes.
+
+   Magit allows you to ignore the staging area if you wish.  As long as
+your staging area is unused, Magit will show your uncomitted changes in
+a section named _Changes_.
+
+   When the staging area is in use, Magit uses two sections: _Unstaged
+changes_ and _Staged changes_.  The _Staged changes_ section shows the
+changes that will be included in the next commit, while the _Unstaged
+changes_ section shows the changes that will be left out.
+
+   To move an unstaged hunk into the staging area, move point into the
+hunk and type `s'.  Likewise, to unstage a hunk, move point into it and
+type `u'.  If point is in a diff header when you type `s' or `u', all
+hunks belonging to that diff are moved at the same time.
+
+   If the region is active when you type `s' or `u', only the changes
+in the region are staged or unstaged.  (This works line by line: if the
+beginning of a line is in the region it is included in the changes,
+otherwise it is not.)
+
+   To change the size of the hunks, you can type `+' or `-' to increase
+and decrease, respectively.  Typing `0' will reset the hunk size to the
+default.
+
+   Typing `C-u s' will ask you for a name of a file to be staged, for
+example to stage files that are hidden.
+
+   To move all hunks of all diffs into the staging area in one go, type
+`S'.  To unstage everything, type `U'.
+
+   Typing `C-u S' will stage all untracked files in addition to the
+changes to tracked files.
+
+   You can discard uncommitted changes by moving point into a hunk and
+typing `k'.  The changes to discard are selected as with `s' and `u'.
+
+   Before committing, you should write a short description of the
+changes.
+
+   Type `c' to pop up a buffer where you can write your change
+description.  Once you are happy with the description, type `C-c C-c'
+in that buffer to perform the commit.
+
+   If you want to write changes in a `ChangeLog' file, you can use `C-x
+4 a' on a diff hunk.
+
+   Typing `c' when the staging area is unused is a special situation.
+Normally, the next commit would be empty, but you can configure Magit
+to do something more useful by customizing the
+`magit-commit-all-when-nothing-staged' variable.  One choice is to
+instruct the subsequent `C-c C-c' to commit all changes.  Another
+choice is stage everything at the time of hitting `c'.
+
+   You can type `C-c C-a' in the buffer with the change description to
+toggle a flag that determines whether the next commit will _amend_ the
+current commit in HEAD.
+
+   Typing `C-c C-s' will toggle the `--signoff' option.  The default is
+determined by the `magit-commit-signoff' customization variable.
+
+   Typing `C-c C-e' will toggle the `--allow-empty' option.  This
+allows you to make commits that serve as notes, without including any
+changes.
+
+   Typing `C-c C-t' will toggle the option to specify the name and
+email address for the commit's author.  The default is determined by
+the `user.name' and `user.email' git configuration settings.
+
+   If you change your mind and don't want to go ahead with your commit
+while you are in the `*magit-log-edit*' buffer, you can just switch to
+another buffer, continue editing there, staging and unstaging things
+until you are happy, and then return to the `*magit-log-edit*' buffer,
+maybe via `C-x b', or by hitting `c' again in a Magit buffer.
+
+   If you want to erase the `*magit-log-edit*' buffer and bury it, you
+can hit `C-c C-k' in it.
+
+   Typing `C' will also pop up the change description buffer, but in
+addition, it will try to insert a ChangeLog-style entry for the change
+that point is in.
+
+
+File: magit.info,  Node: History,  Next: Reflogs,  Prev: Staging and Committing,  Up: Top
+
+7 History
+*********
+
+To show the repository history of your current head, type `l l'.  A new
+buffer will be shown that displays the history in a terse form.  The
+first paragraph of each commit message is displayed, next to a
+representation of the relationships between commits.
+
+   To show the repository history between two branches or between any
+two points of the history, type `l r l'.  You will be prompted to enter
+references for starting point and ending point of the history range; you
+can use auto-completion to specify them.  A typical use case for ranged
+history log display would be `l r l master RET new-feature RET' that
+will display commits on the new-feature branch that are not in master;
+these commits can then be inspected and cherry-picked, for example.
+
+   More thorough filtering can be done by supplying `l' with one or
+more suffix arguments, as displayed in its popup.  `=g' ('Grep') for
+example, limits the output to commits of which the log message matches
+a specific string/regex.
+
+   Typing `l L' (or `l C-u L') will show the log in a more verbose form.
+
+   Magit will show only `magit-log-cutoff-length' entries. `e' will
+show twice as many entries. `C-u e' will show all entries, and given a
+numeric prefix argument, `e' will add this number of entries.
+
+   You can move point to a commit and then cause various things to
+happen with it.  (The following commands work in any list of commits,
+such as the one shown in the _Unpushed commits_ section.)
+
+   Typing `RET' will pop up more information about the current commit
+and move point into the new buffer.  *Note Commit Buffer::.  Typing
+`SPC' and `DEL' will also show the information, but will scroll the new
+buffer up or down (respectively) when typed again.
+
+   Typing `a' will apply the current commit to your current branch.
+This is useful when you are browsing the history of some other branch
+and you want to `cherry-pick' some changes from it.  A typical
+situation is applying selected bug fixes from the development version
+of a program to a release branch.  The cherry-picked changes will not
+be committed automatically; you need to do that explicitly.
+
+   Typing `A' will cherry-pick the current commit and will also commit
+the changes automatically when there have not been any conflicts.
+
+   Typing `v' will revert the current commit.  Thus, it will apply the
+changes made by that commit in reverse.  This is obviously useful to
+cleanly undo changes that turned out to be wrong.  As with `a', you
+need to commit the changes explicitly.
+
+   Typing `C-w' will copy the sha1 of the current commit into the kill
+ring.
+
+   Typing `=' will show the differences from the current commit to the
+"marked" commit.
+
+   You can mark the current commit by typing `.'.  When the current
+commit is already marked, typing `.' will unmark it.  To unmark the
+marked commit no matter where point is, use `C-u .'.
+
+   Some commands, such as `=', will use the current commit and the
+marked commit as implicit arguments.  Other commands will offer the
+marked commit as a default when prompting for their arguments.
+
+
+File: magit.info,  Node: Reflogs,  Next: Commit Buffer,  Prev: History,  Up: Top
+
+8 Reflogs
+*********
+
+You can use `l h' and `l H' to browse your _reflog_, the local history
+of changes made to your repository heads.  Typing `H' will ask for a
+head, while `l h' will show the reflog of `HEAD'.
+
+   The resulting buffer is just like the buffer produced by `l l' and
+`l L' that shows the commit history.
+
+
+File: magit.info,  Node: Commit Buffer,  Next: Diffing,  Prev: Reflogs,  Up: Top
+
+9 Commit Buffer
+***************
+
+When you view a commit (perhaps by selecting it in the log buffer,
+*Note History::), the "commit buffer" is displayed, showing you
+information about the commit and letting you interact with it.
+
+   By placing your cursor within the diff or hunk and typing `a', you
+can apply the same patch to your working copy.  This is useful when you
+want to copy a change from another branch, but don't necessarily want
+to cherry-pick the whole commit.
+
+   By typing `v' you can apply the patch in reverse, removing all the
+lines that were added and adding all the lines that were removed.  This
+is a convenient way to remove a change after determining that it
+introduced a bug.
+
+   If the commit message refers to any other commits in the repository
+by their unique hash, the hash will be highlighted and you will be able
+to visit the referenced commit either by clicking on it or by moving
+your cursor onto it and pressing `RET'.
+
+   The commit buffer maintains a history of the commits it has shown.
+After visiting a referenced commit you can type `C-c C-b' to get back
+to where you came from.  To go forward in the history, type `C-c C-f'.
+There are also `[back]' and `[forward]' buttons at the bottom of the
+buffer.
+
+
+File: magit.info,  Node: Diffing,  Next: Tagging,  Prev: Commit Buffer,  Up: Top
+
+10 Diffing
+**********
+
+Magit typically shows diffs in the "unified" format.
+
+   In any buffer that shows a diff, you can type `e' anywhere within
+the diff to show the two versions of the file in Ediff.  If the diff is
+of a file in the status buffer that needs to be merged, you will be
+able to use Ediff as an interactive merge tool.  Otherwise, Ediff will
+simply show the two versions of the file.
+
+   To show the changes from your working tree to another revision, type
+`d'.  To show the changes between two arbitrary revisions, type `D'.
+
+   You can use `a' within the diff output to apply the changes to your
+working tree.  As usual when point is in a diff header for a file, all
+changes for that file are applied, and when it is in a hunk, only that
+hunk is.  When the region is active, the applied changes are restricted
+to that region.
+
+   Typing `v' will apply the selected changes in reverse.
+
+
+File: magit.info,  Node: Tagging,  Next: Resetting,  Prev: Diffing,  Up: Top
+
+11 Tagging
+**********
+
+Typing `t t' will make a lighweight tag.  Typing `t a' will make an
+annotated tag.  It will put you in the normal `*magit-log-edit' buffer
+for writing commit messages, but typing `C-c C-c' in it will make the
+tag instead.  This is controlled by the `Tag' field that will be added
+to the `*magit-log-edit*' buffer.  You can edit it, if you like.
+
+
+File: magit.info,  Node: Resetting,  Next: Stashing,  Prev: Tagging,  Up: Top
+
+12 Resetting
+************
+
+Once you have added a commit to your local repository, you can not
+change that commit anymore in any way.  But you can reset your current
+head to an earlier commit and start over.
+
+   If you have published your history already, rewriting it in this way
+can be confusing and should be avoided.  However, rewriting your local
+history is fine and it is often cleaner to fix mistakes this way than
+by reverting commits (with `v', for example).
+
+   Typing `x' will ask for a revision and reset your current head to
+it.  No changes will be made to your working tree and staging area.
+Thus, the _Staged changes_ section in the status buffer will show the
+changes that you have removed from your commit history.  You can commit
+the changes again as if you had just made them, thus rewriting history.
+
+   Typing `x' while point is in a line that describes a commit will
+offer this commit as the default revision to reset to.  Thus, you can
+move point to one of the commits in the _Unpushed commits_ section and
+hit `x RET' to reset your current head to it.
+
+   Type `X' to reset your working tree and staging area to the most
+recently committed state.  This will discard your local modifications,
+so be careful.
+
+   You can give a prefix to `x' if you want to reset both the current
+head and your working tree to a given commit.  This is the same as
+first using an unprefixed `x' to reset only the head, and then using
+`X'.
+
+
+File: magit.info,  Node: Stashing,  Next: Branching,  Prev: Resetting,  Up: Top
+
+13 Stashing
+***********
+
+You can create a new stash with `z z'.  Your stashes will be listed in
+the status buffer, and you can apply them with `a' and pop them with
+`A'.  To drop a stash, use `k'.
+
+   With a prefix argument, both `a' and `A' will attempt to reinstate
+the index as well as the working tree from the stash.
+
+   Typing `z -k z' will create a stash just like `z z', but will leave
+the changes in your working tree and index. This makes it easier to,
+for example, test multiple variations of the same change.
+
+   If you just want to make quick snapshots in between edits, you can
+use `z s', which automatically enters a timestamp as description, and
+keeps your working tree and index intact by default.
+
+   You can visit and show stashes in the usual way: Typing `SPC' and
+`DEL' will pop up a buffer with the description of the stash and scroll
+it, typing `RET' will move point into that buffer. Using `C-u RET' will
+move point into that buffer in other window.
+
+
+File: magit.info,  Node: Branching,  Next: The Branch Manager,  Prev: Stashing,  Up: Top
+
+14 Branching
+************
+
+The current branch is indicated in the header of the status buffer.
+You can switch to a different branch by typing `b b'.  This will
+immediately checkout the branch into your working copy, so you
+shouldn't have any local modifications when switching branches.
+
+   If you try to switch to a remote branch, Magit will offer to create a
+local tracking branch for it instead.  This way, you can easily start
+working on new branches that have appeared in a remote repository.
+
+   Typing `b b' while point is at a commit description will offer that
+commit as the default to switch to.  This will result in a detached
+head.
+
+   Typing  `b m' will let you rename a branch. Unless a branch with the
+same name already exists, obviously...
+
+   To create a new branch and switch to it immediately, type `b n'.
+
+   To delete a branch, type `b d'. If you're currently on that branch,
+Magit will offer to switch to the 'master' branch.
+
+   Deleting a branch is only possible if it's already fully merged into
+HEAD or its upstream branch. Unless you type `b D', that is.  Here be
+dragons...
+
+   Typing `b v' will list the local and remote branches in a new buffer
+called `*magit-branches*' from which you can work with them. See *Note
+The Branch Manager:: for more details.
+
+
+File: magit.info,  Node: The Branch Manager,  Next: Wazzup,  Prev: Branching,  Up: Top
+
+15 The Branch Manager
+*********************
+
+The Branch Manager is a separate buffer called `*magit-branches*' with
+its own local key map. The buffer contains both local and remote
+branches. The current local branch is marked by a "*" in front of the
+name.
+
+   To check out a branch, move your cursor to the desired branch and
+press `RET'.
+
+   Typing `k' will delete the branch in the current line, and `C-u k'
+deletes it even if it hasn't been merged into the current local branch.
+Deleting works for both local and remote branches.
+
+   By typing `T' on a local branch, you can change which remote branch
+it's set to track.
+
+
+File: magit.info,  Node: Wazzup,  Next: Merging,  Prev: The Branch Manager,  Up: Top
+
+16 Wazzup
+*********
+
+Typing `w' will show a summary of how your other branches relate to the
+current branch.
+
+   For each branch, you will get a section that lists the commits in
+that branch that are not in the current branch.  The sections are
+initially collapsed; you need to explicitly open them with `TAB' (or
+similar) to show the lists of commits.
+
+   When point is on a _N unmerged commits in ..._ title, the
+corresponding branch will be offered as the default for a merge.
+
+   Hitting `i' on a branch title will ignore this branch in the wazzup
+view.  You can use `C-u w' to show all branches, including the ignored
+ones.  Hitting `i' on an already ignored branch in that view will
+unignore it.
+
+
+File: magit.info,  Node: Merging,  Next: Rebasing,  Prev: Wazzup,  Up: Top
+
+17 Merging
+**********
+
+Magit offers two ways to merge branches: manual and automatic.  A
+manual merge will apply all changes to your working tree and staging
+area, but will not commit them, while an automatic merge will go ahead
+and commit them immediately.
+
+   Type `m m' to initiate merge.
+
+   After initiating a merge, the header of the status buffer might
+remind you that the next commit will be a merge commit (with more than
+one parent).  If you want to abort a manual merge, just do a hard reset
+to HEAD with `X'.
+
+   Merges can fail if the two branches you want to merge introduce
+conflicting changes.  In that case, the automatic merge stops before the
+commit, essentially falling back to a manual merge.  You need to resolve
+the conflicts for example with `e' and stage the resolved files, for
+example with `S'.
+
+   You can not stage individual hunks one by one as you resolve them,
+you can only stage whole files once all conflicts in them have been
+resolved.
+
+
+File: magit.info,  Node: Rebasing,  Next: Interactive Rebasing,  Prev: Merging,  Up: Top
+
+18 Rebasing
+***********
+
+Typing `R' in the status buffer will initiate a rebase or, if one is
+already in progress, ask you how to continue.
+
+   When a rebase is stopped in the middle because of a conflict, the
+header of the status buffer will indicate how far along you are in the
+series of commits that are being replayed.  When that happens, you
+should resolve the conflicts and stage everything and hit `R c' to
+continue the rebase.  Alternatively, hitting `c' or `C' while in the
+middle of a rebase will also ask you whether to continue the rebase.
+
+   Of course, you can initiate a rebase in any number of ways, by
+configuring `git pull' to rebase instead of merge, for example.  Such a
+rebase can be finished with `R' as well.
+
+
+File: magit.info,  Node: Interactive Rebasing,  Next: Rewriting,  Prev: Rebasing,  Up: Top
+
+19 Interactive Rebasing
+***********************
+
+Typing `E' in the status buffer will initiate an interactive rebase.
+This is equivalent to running `git rebase --interactive' at the command
+line. The `git-rebase-todo' file will be opened in an Emacs buffer for
+you to edit. This file is opened using `emacsclient', so just edit this
+file as you normally would, then call the `server-edit' function
+(typically bound to `C-x #') to tell Emacs you are finished editing,
+and the rebase will proceed as usual.
+
+   If you have loaded `rebase-mode.el' (which is included in the Magit
+distribution), the `git-rebase-todo' buffer will be in `rebase-mode'.
+This mode disables normal text editing but instead provides single-key
+commands (shown in the buffer) to perform all the edits that you would
+normally do manually, including changing the operation to be performed
+each commit ("pick", "squash", etc.), deleting (commenting out) commits
+from the list, and reordering commits. You can finish editing the
+buffer and proceed with the rebase by pressing `C-c C-c', which is
+bound to `server-edit' in this mode, and you can abort the rebase with
+`C-c C-k', just like when editing a commit message in Magit.
+
+
+File: magit.info,  Node: Rewriting,  Next: Pushing and Pulling,  Prev: Interactive Rebasing,  Up: Top
+
+20 Rewriting
+************
+
+As hinted at earlier, you can rewrite your commit history.  For
+example, you can reset the current head to an earlier commit with `x'.
+This leaves the working tree unchanged, and the status buffer will show
+all the changes that have been made since that new value of the current
+head.  You can commit these changes again, possibly splitting them into
+multiple commits as you go along.
+
+   Amending your last commit is a common special case of rewriting
+history like this.
+
+   Another common way to rewrite history is to reset the head to an
+earlier commit, and then to cherry pick the previous commits in a
+different order.  You could pick them from the reflog, for example.
+
+   Magit has several commands that can simplify the book keeping
+associated with rewriting.  These commands all start with the `r'
+prefix key.
+
+   Typing `r b' will start a rewrite operation.  You will be prompted
+for a _base_ commit.  This commit and all subsequent commits up until
+the current head are then put in a list of _Pending commits_, after
+which the current head will be reset to the _parent_ of the base
+commit.  This can be configured to behave like `git rebase', i.e.
+exclude the selected base commit from the rewrite operation, with the
+`magit-rewrite-inclusive' variable.
+
+   You would then typically use `a' and `A' to cherry pick commits from
+the list of pending commits in the desired order, until all have been
+applied.  Magit shows which commits have been applied by changing their
+marker from `*' to `.'.
+
+   Using `A' will immediately commit the commit (as usual).  If you
+want to combine multiple previous commits into a single new one, use
+`a' to apply them all to your working tree, and then commit them
+together.
+
+   Magit has no explicit support for rewriting merge commits.  It will
+happily include merge commits in the list of pending commits, but there
+is no way of replaying them automatically.  You have to redo the merge
+explicitly.
+
+   You can also use `v' to revert a commit when you have changed your
+mind.  This will change the `.' mark back to `*'.
+
+   Once you are done with the rewrite, type `r s' to remove the book
+keeping information from the status buffer.
+
+   If you rather wish to start over, type `r a'.  This will abort the
+rewriting, resetting the current head back to the value it had before
+the rewrite was started with `r b'.
+
+   Typing `r f' will _finish_ the rewrite: it will apply all unused
+commits one after the other, as if you would us `A' with all of them.
+
+   You can change the `*' and `.' marks of a pending commit explicitly
+with `r *' and `r .'.
+
+   In addition to a list of pending commits, the status buffer will show
+the _Pending changes_.  This section shows the diff between the
+original head and the current head.  You can use it to review the
+changes that you still need to rewrite, and you can apply hunks from
+it, like from any other diff.
+
+
+File: magit.info,  Node: Pushing and Pulling,  Next: Bisecting,  Prev: Rewriting,  Up: Top
+
+21 Pushing and Pulling
+**********************
+
+Magit will run `git push' when you type `P P'.  If you give a prefix
+argument to `P P', you will be prompted for the repository to push to.
+When no default remote repository has been configured yet for the
+current branch, you will be prompted as well.  Typing `P P' will only
+push the current branch to the remote.  In other words, it will run
+`git push <remote> <branch>'.  The branch will be created in the remote
+if it doesn't exist already.  The local branch will be configured so
+that it pulls from the new remote branch. If you give a double prefix
+argument to `P P', you will be prompted in addition for the target
+branch to push to.  In other words, it will run `git push <remote>
+<branch>:<target>'.
+
+   Typing `f f' will run `git fetch'.  It will prompt for the name of
+the remote to update if there is no default one.  Typing `f o' will
+always prompt for the remote.  Typing `F F' will run `git pull'.  When
+you don't have a default branch configured to be pulled into the
+current one, you will be asked for it.
+
+   If there is a default remote repository for the current branch, Magit
+will show that repository in the status buffer header.
+
+   In this case, the status buffer will also have a _Unpushed commits_
+section that shows the commits on your current head that are not in the
+branch named `<remote>/<branch>'.  This section works just like the
+history buffer: you can see details about a commit with `RET', compare
+two of them with `.' and `=', and you can reset your current head to
+one of them with `x', for example. If you want to push the changes then
+type `P P'.
+
+   When the remote branch has changes that are not in the current
+branch, Magit shows them in a section called _Unpulled changes_.  Typing
+`F F' will fetch and merge them into the current branch.
+
+
+File: magit.info,  Node: Submodules,  Next: Using Magit Extensions,  Prev: Bisecting,  Up: Top
+
+22 Submodules
+*************
+
+`M u'
+     Update the submodules, with a prefix argument it will initializing.
+
+`M i'
+     Initialize the submodules.
+
+`M b'
+     Update and initialize the submodules in one go.
+
+`M s'
+     Synchronizes submodules' remote URL configuration setting to the
+     value specified in .gitmodules.
+
+
+File: magit.info,  Node: Bisecting,  Next: Submodules,  Prev: Pushing and Pulling,  Up: Top
+
+23 Bisecting
+************
+
+Magit supports bisecting by showing how many revisions and steps are
+left to be tested in the status buffer. You can control the bisect
+session from both the status and from log buffers with the `B' key menu.
+
+   Typing `B s' will start a bisect session.  You will be prompted for
+a revision that is known to be bad (defaults to _HEAD_) and for a
+revision that is known to be good (defaults to the revision at point if
+there is one). git will select a revision for you to test, and Magit
+will update its status buffer accordingly.
+
+   You can tell git that the current revision is good with `B g', that
+it is bad with `B b' or that git should skip it with `B k'. You can
+also tell git to go into full automatic mode by giving it the name of a
+script to run for each revision to test with `B u'.
+
+   The current status can be shown as a log with `B l'. It contains the
+revisions that have already been tested and your decisions about their
+state.
+
+   The revisions left to test can be visualized in gitk with `B v'.
+
+   When you're finished bisecting you have to reset the session with `B
+r'.
+
+
+File: magit.info,  Node: Using Magit Extensions,  Next: Using Git Directly,  Prev: Submodules,  Up: Top
+
+24 Magit Extensions
+*******************
+
+* Menu:
+
+* Activating extensions::
+* Interfacing with Subversion::
+* Interfacing with Topgit::
+* Interfacing with StGit::
+* Developing Extensions::
+
+
+File: magit.info,  Node: Activating extensions,  Next: Interfacing with Subversion,  Up: Using Magit Extensions
+
+24.1 Activating extensions
+==========================
+
+Magit comes with a couple of shipped extensions that allow interaction
+with `git-svn', `topgit' and `stgit'. See following sections for
+specific details on how to use them.
+
+   Extensions can be activated globally or on a per-repository basis.
+Since those extensions are implemented as minor modes, one can use for
+example `M-x magit-topgit-mode' to toggle the `topgit' extension,
+making the corresponding section and commands (un)available.
+
+   In order to do that automatically (and for every repository), one can
+use for example:
+
+     (add-hook 'magit-mode-hook 'turn-on-magit-topgit)
+
+   Magit also allows configuring different extensions, based on the git
+repository configuration.
+
+     (add-hook 'magit-mode-hook 'magit-load-config-extensions)
+
+   This will read git configuration variables and activate the relevant
+extensions.
+
+   For example, after running the following commands, the `topgit'
+extension will be loaded for every repository, while the `svn' one will
+be loaded only for the current one.
+
+     $ git config --global --add magit.extension topgit
+     $ git config --add magit.extension svn
+
+   Note the `--add' flag, which means that each extension gets its own
+line in the `config' file.
+
+
+File: magit.info,  Node: Interfacing with Subversion,  Next: Interfacing with Topgit,  Prev: Activating extensions,  Up: Using Magit Extensions
+
+24.2 Interfacing with Subversion
+================================
+
+Typing `N r' runs `git svn rebase', typing `N c' runs `git svn dcommit'
+and typing `N f' runs `git svn fetch'.
+
+   `N s' will prompt you for a (numeric, Subversion) revision and then
+search for a corresponding Git sha1 for the commit. This is limited to
+the path of the remote Subversion repository. With a prefix (`C-u N s'
+the user will also be prompted for a branch to search in.
+
+
+File: magit.info,  Node: Interfacing with Topgit,  Next: Interfacing with StGit,  Prev: Interfacing with Subversion,  Up: Using Magit Extensions
+
+24.3 Interfacing with Topgit
+============================
+
+Topgit (http://repo.or.cz/r/topgit.git) is a patch queue manager that
+aims at being close as possible to raw Git, which makes it easy to use
+with Magit. In particular, it does not require to use a different set of
+commands for "commit", "update",… operations.
+
+   `magit-topgit.el' provides basic integration with Magit, mostly by
+providing a "Topics" section.
+
+   Topgit branches can be created the regular way, by using a "t/"
+prefix by convention. So, creating a "t/foo" branch will actually
+populate the "Topics" section with one more branch after committing
+`.topdeps' and `.topmsg'.
+
+   Also, the way we pull (see *Note Pushing and Pulling::) such a
+branch is slightly different, since it requires updating the various
+dependencies of that branch. This should be mostly transparent, except
+in case of conflicts.
+
+
+File: magit.info,  Node: Interfacing with StGit,  Next: Developing Extensions,  Prev: Interfacing with Topgit,  Up: Using Magit Extensions
+
+24.4 Interfacing with StGit
+===========================
+
+StGit (http://www.procode.org/stgit) is a Python application providing
+similar functionality to Quilt (i.e. pushing/popping patches to/from a
+stack) on top of Git. These operations are performed using Git commands
+and the patches are stored as Git commit objects, allowing easy merging
+of the StGit patches into other repositories using standard Git
+functionality.
+
+   `magit-stgit.el' provides basic integration with Magit, mostly by
+providing a "Series" section, whose patches can be seen as regular
+commits through the "visit" action.
+
+   You can change the current patch in a series with the "apply" action,
+as well as you can delete them using the "discard" action.
+
+   Additionally, the `magit-stgit-refresh' and `magit-stgit-rebase'
+commands let you perform the respective StGit operations.
+
+
+File: magit.info,  Node: Developing Extensions,  Prev: Interfacing with StGit,  Up: Using Magit Extensions
+
+24.5 Developing Extensions
+==========================
+
+Magit provides a generic mechanism to allow cooperation with Git-related
+systems, such as foreign VCS, patch systems,…
+
+   In particular it allows to:
+
+   * Define sections to display specific informations about the current
+     state of the repository, and place them relatively to existing
+     sections.
+
+     `magit-define-inserter' automagically defines two hooks called
+     `magit-before-insert-SECTION-hook' and
+     `magit-after-insert-SECTION-hook' that allow to generate and place
+     more sections.
+
+     In the following example, we use the builtin "stashes" section to
+     place our own "foo" one.
+
+          (magit-define-inserter foo ()
+            (magit-git-section 'foo
+                               "Foo:" 'foo-wash-function
+                               "foo" "arg1" "arg2"))
+          (add-hook 'magit-after-insert-stashes-hook 'magit-insert-foo)
+
+   * Define new types of objects in those sections.
+
+     The function `foo-wash-function' defined above post-processes each
+     line of the output of the "git foo arg1 arg2" command, and is able
+     to associate a type to certain lines.
+
+     A simple implementation could be:
+
+          (defun foo-wash-function ()
+            (let ((foo (buffer-substring (line-beginning-position) (line-end-position))))
+              (goto-char (line-beginning-position))
+              (magit-with-section foo 'foo
+                (magit-set-section-info foo)
+                (forward-line))))
+
+     In this case, every line of the command output is transformed into
+     an object of type `'foo'.
+
+   * Alter behavior of generic commands to dispatch them correctly to
+     the relevant system, optionally making use of the newly defined
+     types.
+
+          (magit-add-action (item info "discard")
+            ((foo)
+             (do-something-meaningful-for-discarding-a-foo)))
+
+     This will alter the behavior of `k', when applied to those objects.
+
+   * Plug a different logic into basic commands, to reflect the
+     presence of the extension.
+
+     `magit-define-command' automagically defines a
+     `magit-CMD-command-hook' that can contain a list of functions to
+     call before the actual core code. Execution stops after the first
+     hook that returns a non-nil value. This leaves room for extension
+     logic.
+
+          (add-hook 'magit-create-branch-command-hook 'foo-create-branch)
+
+     The function `foo-create-branch' will be called each time an
+     attempt is made to create a branch, and can, for example, react to
+     a certain name convention.
+
+   * Define new commands and associated menu.
+
+     This part is not really specific to extensions, except that menus
+     take place in the "Extensions" submenu.
+
+
+   It is suggested that Magit extensions authors stick to the
+convention of making extensions minor modes. This has many advantages,
+including the fact that users are able to toggle extensions, and that
+it's easy to configure a specific set of extensions for a given
+repository.
+
+   Shipped extensions can serve as an example of how to develop new
+extensions.
+
+   Basically a `foo' extension should provide a `magit-foo-mode' minor
+mode, as well as a `turn-on-magit-foo' function.  The main task of the
+minor mode is to register/unregister the various hooks that the
+extension requires. The registered actions on the other hand can be
+left alone and activated globally, since they can be run only on
+displayed items, which won't happen when the minor mode is off.
+
+   Don't forget to call `magit-refresh' when the minor mode is toggled
+interactively, so that the relevant sections can be shown or hidden.
+
+
+File: magit.info,  Node: Using Git Directly,  Next: Customization,  Prev: Using Magit Extensions,  Up: Top
+
+25 Using Git Directly
+*********************
+
+For situations when Magit doesn't do everything you need, you can run
+raw Git commands using `:'.  This will prompt for a Git command, run
+it, and refresh the status buffer.  The output can be viewed by typing
+`$'.
+
+
+File: magit.info,  Node: Customization,  Next: Frequently Asked Questions,  Prev: Using Git Directly,  Up: Top
+
+26 Customization
+****************
+
+The following variables can be used to adapt Magit to your workflow:
+
+`magit-git-executable'
+     The name of the Git executable.
+
+`magit-git-standard-options'
+     Standard options when running Git.
+
+`magit-repo-dirs'
+     Directories containing Git repositories.
+
+     Magit will look into these directories for Git repositories and
+     offer them as choices for `magit-status'.
+
+`magit-repo-dirs-depth'
+     The maximum depth to look for Git repos.
+
+     When looking for a Git repository below the directories in
+     `magit-repo-dirs', Magit will only descend this many levels deep.
+
+`magit-save-some-buffers'
+     Non-nil means that `magit-status' will save modified buffers
+     before running.  Setting this to `t' will ask which buffers to
+     save, setting it to `'dontask' will save all modified buffers
+     without asking.
+
+`magit-save-some-buffers-predicate'
+     Specifies a predicate function on `magit-save-some-buffers' to
+     determine which unsaved buffers should be prompted for saving.
+
+`magit-commit-all-when-nothing-staged'
+     Determines what `magit-log-edit' does when nothing is staged.
+     Setting this to `nil' will make it do nothing, setting it to `t'
+     will arrange things so that the actual commit command will use the
+     `--all' option, setting it to `'ask' will first ask for
+     confirmation whether to do this, and setting it to `'ask-stage'
+     will cause all changes to be staged, after a confirmation.
+
+`magit-commit-signoff'
+     When performing `git commit' adds `--signoff'.
+
+`magit-log-cutoff-length'
+     The maximum number of commits to show in the `log' and `whazzup'
+     buffers.
+
+`magit-log-infinite-length'
+     Number of log used to show as maximum for
+     `magit-log-cutoff-length'.
+
+`magit-log-auto-more'
+     Insert more log entries automatically when moving past the last
+     entry.
+
+     Only considered when moving past the last entry with
+     `magit-goto-next-section'.
+
+`magit-process-popup-time'
+     Popup the process buffer if a command takes longer than this many
+     seconds.
+
+`magit-revert-item-confirm'
+     Require acknowledgment before reverting an item.
+
+`magit-log-edit-confirm-cancellation'
+     Require acknowledgment before canceling the log edit buffer.
+
+`magit-remote-ref-format'
+     What format to use for autocompleting refs, in pariticular for
+     remotes.
+
+     Autocompletion is used by functions like `magit-checkout',
+     `magit-interactive-rebase' and others which offer branch name
+     completion.
+
+     The value `'name-then-remote' means remotes will be of the form
+     `name (remote)', while the value `'remote-slash-name' means that
+     they'll be of the form `remote/name'. I.e. something that's listed
+     as `remotes/upstream/next' by `git branch -l -a' will be
+     `upstream/next'.
+
+`magit-process-connection-type'
+     Connection type used for the git process.
+
+     `nil' mean pipe, it is usually faster and more efficient, and work
+     on cygwin.  `t' mean pty, it enable magit to prompt for passphrase
+     when needed.
+
+`magit-completing-read-function'
+     Function to be called when requesting input from the user.
+
+`magit-create-branch-behaviour'
+     Where magit will create a new branch if not supplied a branchname
+     or ref.
+
+     The value `'at-head' means a new branch will be created at the tip
+     of your current branch, while the value `'at-point' means magit
+     will try to find a valid reference at point...
+
+`magit-status-buffer-switch-function'
+     Function for `magit-status' to use for switching to the status
+     buffer.
+
+     The function is given one argument, the status buffer.
+
+`magit-rewrite-inclusive'
+     Whether magit includes the selected base commit in a rewrite
+     operation.
+
+     `t' means both the selected commit as well as any subsequent
+     commits will be rewritten. This is magit's default behaviour,
+     equivalent to `git rebase -i ${REV~1}'
+
+
+       A'---B'---C'---D'
+       ^
+
+     `nil' means the selected commit will be literally used as `base',
+     so only subsequent commits will be rewritten. This is consistent
+     with git-rebase, equivalent to `git rebase -i ${REV}', yet more
+     cumbersome to use from the status buffer.
+
+
+       A---B'---C'---D'
+       ^
+
+`magit-topgit-executable'
+     The name of the TopGit executable.
+
+`magit-topgit-branch-prefix'
+     Convention prefix for topic branch creation.
+
+
+
+File: magit.info,  Node: Frequently Asked Questions,  Prev: Customization,  Up: Top
+
+27 Frequently Asked Questions
+*****************************
+
+* Menu:
+
+* FAQ - Changes::
+* FAQ 1 - Troubleshooting::
+* FAQ 2 - Display issues::
+
+
+File: magit.info,  Node: FAQ - Changes,  Next: FAQ 1 - Troubleshooting,  Up: Frequently Asked Questions
+
+27.1 Changes
+============
+
+   * v1.1: Changed the way extensions work. Previously, they were
+     enabled unconditionally once the library was loaded. Now they are
+     minor modes that need to be activated explicitly (potentially on a
+     per-repository basis). See *Note Activating extensions::.
+
+
+
+File: magit.info,  Node: FAQ 1 - Troubleshooting,  Next: FAQ 2 - Display issues,  Prev: FAQ - Changes,  Up: Frequently Asked Questions
+
+27.2 Troubleshooting
+====================
+
+* Menu:
+
+* FAQ 1-1::    How do I get raw error messages from git?
+
+
+File: magit.info,  Node: FAQ 1-1,  Up: FAQ 1 - Troubleshooting
+
+27.2.1 Question 1.1
+-------------------
+
+How do I get raw error messages from git?
+
+Answer
+......
+
+If a command goes wrong, you can hit `$' to access the git process
+buffer. There, the entire trace for the latest operation is available.
+
+
+File: magit.info,  Node: FAQ 2 - Display issues,  Prev: FAQ 1 - Troubleshooting,  Up: Frequently Asked Questions
+
+27.3 Display issues
+===================
+
+* Menu:
+
+* FAQ 2-1::    How do I fix international characters display?
+
+
+File: magit.info,  Node: FAQ 2-1,  Up: FAQ 2 - Display issues
+
+27.3.1 Question 2.1
+-------------------
+
+How do I fix international characters display?
+
+Answer
+......
+
+Please make sure your Magit buffer uses a compatible coding system.  In
+the particular case of file names, git itself quotes them by default.
+You can disable this with one of the following approaches:
+
+     $ git config core.quotepath false
+
+   or
+
+     (setq magit-git-standard-options (append magit-git-standard-options
+                                              '("-c" "core.quotepath=false")))
+
+   The latter might not work in old versions of git.
+
+
+
+Tag Table:
+Node: Top639
+Node: Introduction1592
+Node: Acknowledgments3064
+Node: Sections3744
+Node: Status6294
+Node: Untracked files9033
+Node: Staging and Committing10237
+Node: History14135
+Node: Reflogs17315
+Node: Commit Buffer17719
+Node: Diffing19045
+Node: Tagging20032
+Node: Resetting20481
+Node: Stashing22005
+Node: Branching23063
+Node: The Branch Manager24441
+Node: Wazzup25157
+Node: Merging25948
+Node: Rebasing26998
+Node: Interactive Rebasing27824
+Node: Rewriting29116
+Node: Pushing and Pulling32141
+Node: Submodules34068
+Node: Bisecting34488
+Node: Using Magit Extensions35703
+Node: Activating extensions36000
+Node: Interfacing with Subversion37384
+Node: Interfacing with Topgit37982
+Node: Interfacing with StGit39010
+Node: Developing Extensions40008
+Node: Using Git Directly43786
+Node: Customization44157
+Node: Frequently Asked Questions48703
+Node: FAQ - Changes48934
+Node: FAQ 1 - Troubleshooting49342
+Node: FAQ 1-149590
+Node: FAQ 2 - Display issues49894
+Node: FAQ 2-150123
+
+End Tag Table
diff --git a/.emacs.d/elpa/magit-1.2.0/rebase-mode.el b/.emacs.d/elpa/magit-1.2.0/rebase-mode.el
new file mode 100644
index 0000000..1ccfb54
--- /dev/null
+++ b/.emacs.d/elpa/magit-1.2.0/rebase-mode.el
@@ -0,0 +1,322 @@
+;;; rebase-mode -- edit git rebase files.
+
+;; Copyright (C) 2010  Phil Jackson
+;; Copyright (C) 2011  Peter J Weisberg
+;;
+;; Magit is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Allows the editing of a git rebase file (which you might get when
+;; using 'git rebase -i' or hitting 'E' in Magit). Assumes editing is
+;; happening in a server.
+
+;;; Code:
+
+(require 'server)
+
+(defgroup rebase-mode nil
+  "Customize Rebase Mode"
+  :group 'faces)
+
+(defface rebase-mode-killed-action-face
+  '((((class color))
+     :inherit font-lock-comment-face
+     :strike-through t))
+  "Action lines in the rebase TODO list that have been commented out."
+  :group 'rebase-mode)
+
+(defface rebase-mode-description-face
+  '((t :inherit font-lock-comment-face))
+  "Face for one-line commit descriptions"
+  :group 'rebase-mode)
+
+(defconst rebase-mode-action-line-re
+  (rx
+   line-start
+   (? "#")
+   (group
+    (|
+     (any "presf")
+     "pick"
+     "reword"
+     "edit"
+     "squash"
+     "fixup"))
+   (char space)
+   (group
+    (** 4 40 hex-digit)) ;sha1
+   (char space)
+   (group
+    (* not-newline)))
+  "Regexp that matches an action line in a rebase buffer.")
+
+(defconst rebase-mode-exec-line-re
+  (rx
+   line-start
+   (? "#")
+   (group
+    (| "x"
+       "exec"))
+   (char space)
+   (group
+    (* not-newline)))
+  "Regexp that matches an exec line in a rebase buffer.")
+
+(defconst rebase-mode-dead-line-re
+  (rx-to-string `(and line-start
+                      (char ?#)
+                      (or (regexp ,(substring rebase-mode-action-line-re 1))
+                          (regexp ,(substring rebase-mode-exec-line-re 1)))) t)
+  "Regexp that matches a commented-out exec or action line in a rebase buffer.")
+
+(defvar rebase-mode-font-lock-keywords
+  (list
+   (list rebase-mode-action-line-re
+         '(1 font-lock-keyword-face)
+         '(2 font-lock-builtin-face)
+         '(3 'rebase-mode-description-face))
+   (list rebase-mode-exec-line-re
+         '(1 font-lock-keyword-face))
+   (list (rx line-start (char "#") (* not-newline)) 0 font-lock-comment-face)
+   (list rebase-mode-dead-line-re 0 ''rebase-mode-killed-action-face t))
+  "Font lock keywords for `rebase-mode'.")
+
+(defvar key-to-action-map
+  '(("c" . "pick")
+    ("r" . "reword")
+    ("e" . "edit")
+    ("s" . "squash")
+    ("f" . "fixup"))
+  "Mapping from key to action.")
+
+(defvar rebase-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "q") 'server-edit)
+    (define-key map (kbd "C-c C-c") 'server-edit)
+
+    (define-key map (kbd "a") 'rebase-mode-abort)
+    (define-key map (kbd "C-c C-k") 'rebase-mode-abort)
+
+    (define-key map (kbd "M-p") 'rebase-mode-move-line-up)
+    (define-key map (kbd "M-n") 'rebase-mode-move-line-down)
+    (define-key map (kbd "k") 'rebase-mode-kill-line)
+    (define-key map (kbd "x") 'rebase-mode-exec)
+
+    (define-key map (kbd "n") 'forward-line)
+    (define-key map (kbd "p") '(lambda(n)
+                                 (interactive "p")
+                                 (forward-line (* n -1))))
+    (define-key map [remap undo] 'rebase-mode-undo)
+    map)
+  "Keymap for rebase-mode.  Note this will be added to by the
+top-level code which defines the edit functions.")
+
+(require 'easymenu)
+(easy-menu-define rebase-mode-menu rebase-mode-map
+  "Rebase-mode menu"
+  '("Rebase"
+    ["Pick" rebase-mode-pick t]
+    ["Reword" rebase-mode-reword t]
+    ["Edit" rebase-mode-edit t]
+    ["Squash" rebase-mode-squash t]
+    ["Fixup" rebase-mode-fixup t]
+    ["Kill" rebase-mode-kill-line t]
+    ["Move Down" rebase-mode-move-line-down t]
+    ["Move Up" rebase-mode-move-line-up t]
+    ["Execute" rebase-mode-exec t]
+    "---"
+    ["Abort" rebase-mode-abort t]
+    ["Done" server-edit t]))
+
+;; create the functions which edit the action lines themselves (based
+;; on `key-to-action-map' above)
+(mapc (lambda (key-action)
+        (let ((fun-name (intern (concat "rebase-mode-" (cdr key-action)))))
+          ;; define the function
+          (eval `(defun ,fun-name ()
+                   (interactive)
+                   (rebase-mode-edit-line ,(cdr key-action))))
+
+          ;; bind the function in `rebase-mode-map'
+          (define-key rebase-mode-map (car key-action) fun-name)))
+      key-to-action-map)
+
+(defun rebase-mode-edit-line (change-to)
+  "Change the keyword at the start of the current action line to
+that of CHANGE-TO."
+  (when (rebase-mode-looking-at-action)
+    (let ((buffer-read-only nil)
+          (start (point)))
+      (goto-char (point-at-bol))
+      (delete-region (point) (progn (forward-word 1) (point)))
+      (insert change-to)
+      (goto-char start))))
+
+(defun rebase-mode-looking-at-action ()
+  "Return non-nil if looking at an action line."
+  (save-excursion
+    (goto-char (point-at-bol))
+    (looking-at rebase-mode-action-line-re)))
+
+(defun rebase-mode-looking-at-action-or-exec ()
+  "Return non-nil if looking at an action line or exec line."
+  (save-excursion
+    (goto-char (point-at-bol))
+    (or (looking-at rebase-mode-action-line-re)
+        (looking-at rebase-mode-exec-line-re))))
+
+(defun rebase-mode-looking-at-exec ()
+  "Return non-nil if cursor is on an exec line."
+  (string-match rebase-mode-exec-line-re (thing-at-point 'line)))
+
+(defun rebase-mode-looking-at-killed-exec ()
+  "Return non-nil if looking at an exec line that has been commented out"
+  (let ((line (thing-at-point 'line)))
+    (and (eq (aref line 0) ?#)
+         (string-match rebase-mode-exec-line-re line))))
+
+(defun rebase-mode-move-line-up ()
+  "Move the current action line up."
+  (interactive)
+  (when (rebase-mode-looking-at-action-or-exec)
+    (let ((buffer-read-only nil)
+          (col (current-column)))
+      (transpose-lines 1)
+      (forward-line -2)
+      (move-to-column col))))
+
+(defun rebase-mode-move-line-down ()
+  "Assuming the next line is also an action line, move the current line down."
+  (interactive)
+  ;; if we're on an action and the next line is also an action
+  (when (and (rebase-mode-looking-at-action-or-exec)
+             (save-excursion
+               (forward-line)
+               (rebase-mode-looking-at-action-or-exec)))
+    (let ((buffer-read-only nil)
+          (col (current-column)))
+      (forward-line 1)
+      (transpose-lines 1)
+      (forward-line -1)
+      (move-to-column col))))
+
+(defun rebase-mode-abort ()
+  "Abort this rebase (by emptying the buffer, saving and closing
+server connection)."
+  (interactive)
+  (when (or (not (buffer-modified-p))
+            (y-or-n-p "Abort this rebase? "))
+    (let ((buffer-read-only nil))
+      (delete-region (point-min) (point-max))
+      (save-buffer)
+      (server-edit))))
+
+(defun rebase-mode-kill-line ()
+  "Kill the current action line."
+  (interactive)
+  (when (and (not (eq (char-after (point-at-bol)) ?#))
+             (rebase-mode-looking-at-action-or-exec))
+    (beginning-of-line)
+    (let ((buffer-read-only nil))
+      (insert "#"))
+    (forward-line)))
+
+(defun rebase-mode-exec (edit)
+  "Prompt the user for a shell command to be executed, and add it to
+the todo list.
+
+If the cursor is on a commented-out exec line, uncomment the
+current line instead of prompting.
+
+When the prefix argument EDIT is non-nil and the cursor is on an
+exec line, edit that line instead of inserting a new one.  If the
+exec line was commented out, also uncomment it."
+  (interactive "P")
+  (cond
+   ((and edit (rebase-mode-looking-at-exec))
+    (let ((new-line (rebase-mode-read-exec-line
+                     (match-string-no-properties 2 (thing-at-point 'line))))
+          (inhibit-read-only t))
+      (delete-region (point-at-bol) (point-at-eol))
+      (if (not (equal "" new-line))
+          (insert "exec " new-line)
+        (delete-char -1)
+        (forward-line))
+      (move-beginning-of-line nil)))
+   ((rebase-mode-looking-at-killed-exec)
+    (save-excursion
+      (beginning-of-line)
+      (let ((buffer-read-only nil))
+        (delete-char 1))))
+   (t
+    (let ((inhibit-read-only t)
+          (line (rebase-mode-read-exec-line)))
+      (unless (equal "" line)
+        (move-end-of-line nil)
+        (newline)
+        (insert (concat "exec " line))))
+    (move-beginning-of-line nil))))
+
+(defun rebase-mode-read-exec-line (&optional initial-line)
+  (read-shell-command "Execute: " initial-line))
+
+(defun rebase-mode-undo (&optional arg)
+  "A thin wrapper around `undo', which allows undoing in
+read-only buffers."
+  (interactive "P")
+  (let ((inhibit-read-only t))
+    (undo arg)))
+
+;;;###autoload
+(define-derived-mode rebase-mode special-mode "Rebase"
+  "Major mode for editing of a Git rebase file.
+
+Rebase files are generated when you run 'git rebase -i' or run
+`magit-interactive-rebase'.  They describe how Git should perform
+the rebase.  See the documentation for git-rebase (e.g., by
+running 'man git-rebase' at the command line) for details."
+  (setq font-lock-defaults '(rebase-mode-font-lock-keywords t t)))
+
+(defun rebase-mode-show-keybindings ()
+  "Modify the \"Commands:\" section of the comment Git generates
+at the bottom of the file so that in place of the one-letter
+abbreviation for the command, it shows the command's keybinding.
+By default, this is the same except for the \"pick\" command."
+  (save-excursion
+    (goto-char (point-min))
+    (while (search-forward-regexp "^#  \\(.\\), \\([[:alpha:]]+\\) = " nil t)
+      (let ((start (match-beginning 1))
+            (end (match-end 1))
+            (command (intern (concat "rebase-mode-" (match-string 2)))))
+        (when (fboundp command)
+          (let ((overlay (make-overlay start end)))
+            (overlay-put overlay
+                         'display
+                         (key-description (where-is-internal command nil t)))))))))
+
+(add-hook 'rebase-mode-hook 'rebase-mode-show-keybindings t)
+
+(defun rebase-mode-disable-before-save-hook ()
+  (set (make-local-variable 'before-save-hook) nil))
+
+(add-hook 'rebase-mode-hook 'rebase-mode-disable-before-save-hook)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist
+             '("git-rebase-todo" . rebase-mode))
+
+(provide 'rebase-mode)
+
+;;; rebase-mode.el ends here
diff --git a/.emacs.d/elpa/magit-1.2.0/rebase-mode.elc b/.emacs.d/elpa/magit-1.2.0/rebase-mode.elc
new file mode 100644
index 0000000..ba80a48
Binary files /dev/null and b/.emacs.d/elpa/magit-1.2.0/rebase-mode.elc differ
[from now] 2013/09/05 11:51:20

diff --git a/.bashrc b/.bashrc
index 2bba9cc..ab386b1 100644
--- a/.bashrc
+++ b/.bashrc
@@ -7,10 +7,17 @@ PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting
 # emacs23.4
 alias emacs='/usr/local/Cellar/emacs/23.4/Emacs.app/Contents/MacOS/Emacs -nw'

+# rmtrash
+alias rm='rmtrash'
+alias mv='mv -i'
+
 # ag
 # http://qiita.com/yuyuchu3333/items/4c57186e37db9eb3db15
 alias ag='ag --smart-case --color --stats' # --pager "less -F"'

+# show path
+alias showpath='echo -e ${PATH//:/\\n}'
+
 #THIS MUST BE AT THE END OF THE FILE FOR GVM TO WORK!!!
 [[ -s "/Users/kwatanabe/.gvm/bin/gvm-init.sh" ]] && source "/Users/kwatanabe/.gvm/bin/gvm-init.sh"
[from now] 2013/09/05 11:51:59

diff --git a/.bashrc b/.bashrc
index ab386b1..0eec55f 100644
--- a/.bashrc
+++ b/.bashrc
@@ -16,7 +16,10 @@ alias mv='mv -i'
 alias ag='ag --smart-case --color --stats' # --pager "less -F"'

 # show path
-alias showpath='echo -e ${PATH//:/\\n}'
+alias show_path='echo -e ${PATH//:/\\n}'
+
+# reload bashrc
+alias reload_bashrc='

 #THIS MUST BE AT THE END OF THE FILE FOR GVM TO WORK!!!
 [[ -s "/Users/kwatanabe/.gvm/bin/gvm-init.sh" ]] && source "/Users/kwatanabe/.gvm/bin/gvm-init.sh"
[from now] 2013/09/05 11:52:14

diff --git a/.bashrc b/.bashrc
index 0eec55f..ffd65ab 100644
--- a/.bashrc
+++ b/.bashrc
@@ -19,7 +19,7 @@ alias ag='ag --smart-case --color --stats' # --pager "less -F"'
 alias show_path='echo -e ${PATH//:/\\n}'

 # reload bashrc
-alias reload_bashrc='
+alias reload_bashrc='source ~/.bashrc'

 #THIS MUST BE AT THE END OF THE FILE FOR GVM TO WORK!!!
 [[ -s "/Users/kwatanabe/.gvm/bin/gvm-init.sh" ]] && source "/Users/kwatanabe/.gvm/bin/gvm-init.sh"
[from now] 2013/09/05 16:13:08

diff --git a/.uncrustifyconfig b/.uncrustifyconfig
new file mode 100644
index 0000000..d4e01b2
--- /dev/null
+++ b/.uncrustifyconfig
@@ -0,0 +1,715 @@
+##### Uncrustify config
+
+### Preprocessor
+## http://qiita.com/items/dd7c5ffdff27451dae16
+# #if、#ifdef、#ifndef〜#else〜#endifブロック内のプロプロセッサをインデントするかどうか。{ ignore, add, remove, force }
+pp_indent = add
+# ソースコードのインデントレベルに合わせてインデントするかどうか。{ true, false }
+pp_indent_at_level = true
+# pp_indent_at_level=falseの場合のインデント幅 { number }
+pp_indent_count = 4
+# #if、#ifdef、#ifndef〜#else〜#endifブロック内のプリプロセッサの#の後から半角空白でインデントするかどうか { ignore, add, remove, force }
+pp_space = remove
+# #の後に加える半角空白数 { number }
+pp_space_count = 0
+# #regionと#endregion (C#言語)、#pragmra region (C/C++) に対するインデント { number }
+pp_indent_region = 0
+# #regionと#endregionの間のコードをインデントするかどうか { true, false }
+pp_region_indent_code = false
+# pp_indent_at_level=trueの場合: ファイルレベルにない'#if'、'#else'、'#endif'に対するインデント位置(N桁)を固定する { number }
+pp_indent_if = 0
+# ファイルレベルにない'#if'、'#else'、'#endif'の間のコードをインデントするかどうか { true, false }
+pp_if_indent_code = true
+# '#define'をブレースレベルに合わせてインデントするかどうか { true, false }
+pp_define_at_level = false
+
+### General
+## http://qiita.com/items/d8998dd5e90697744e3c
+# 出力に用いる改行コード { auto, lf, crlf, cr }
+newlines = auto
+# 入力ファイルのタブサイズ { number }
+input_tab_size = 4
+# 出力ファイルのタブサイズ { number }
+output_tab_size = 4
+# 文字列エスケープ文字に対するASCIIコード (通常は'\'(92)、Pawnの場合'^'(94)) { number }
+string_escape_char = 92
+# '>='と'>>='を'void f(list<list<B>>=val);'のテンプレートの一部と解釈させるかどうか { true, false }
+tok_split_gte = false
+# UTF-8ファイルのBOMコードへの対応 (推奨'remove') { ignore, add, remove, force }
+utf8_bom = add
+# 値128〜255を持つバイトを含むUTF-8でないファイルの場合、出力をUTF-8とするかどうか { true, false }
+utf8_byte = false
+# 出力エンコーディングを強制的にUTF-8にするかどうか { true, false }
+utf8_force = true
+
+### Indent
+## http://qiita.com/items/b3fee3560e4ae746b468
+# インデントレベルのインデント幅 (半角空白数) (通常 2、3、4、8) { number }
+indent_columns = 4
+# '('や'='の行送りの後のインデントを上書き。マイナスの場合はインデントを継続。 { number }
+indent_continue = 0
+# コードをインデントする時にどのようにインデントするか。 { 0: 半角空白のみ 1: インデントはタブ、位置揃えは半角空白 2: インデントも位置揃えもタブ (タブストップ以外は半角空白) }
+indent_with_tabs = 0
+# コードのインデントレベルでないコメントをタブ位置までタブ文字でインデントするか。falseの場合、半角空白のみ。 (indent_with_tabs=2の場合のみ) { true, false }
+indent_cmt_with_tabs = false
+# '\'-改行でされた文字列を位置揃えさせるかどうか。これ、いろいろ試したけど効かないな。 { true, false }
+indent_align_string = true
+# '{'をレベルからインデントさせる半角空白数 { number }
+indent_brace = 0
+# ボディレベルからブレースをインデントさせるかどうか { true, false }
+indent_braces = false
+# 関数ブレースのインデントの無効化 (indent_bracesがtrueの時のみ) { true, false }
+indent_braces_no_func = true
+# クラスブレースのインデントの無効化 (indent_bracesがtrueの時のみ) { true, false }
+indent_braces_no_class = true
+# 構造体ブレースのインデントの無効化 (indent_bracesがtrueの時のみ) { true, false }
+indent_braces_no_struct = true
+# ブレースオーナーの文字数ベースでインデントする (例: 'if'なら空白3文字、'for'なら空白4文字) { true, false}
+indent_brace_parent = false
+# 'namespace'のボディをインデントさせるかどうか { true, false }
+indent_namespace = true
+# 名前空間ブロックをインデントさせる空白数 { number } 0=>ベースインデント幅に依存
+indent_namespace_level = 0
+# 名前空間のボディがこの数字よりも長い場合、インデントしない。 (indent_namespace=trueの場合のみ) (0: 無制限) { number }
+indent_namespace_limit = 0
+# 'extern "C"'ボディをインデントさせるかどうか { true, false }
+indent_extern = true
+# 'class'ボディをインデントさせるかどうか { true, false }
+indent_class = true
+# クラス宣言の継承のコロンに続く文字をインデントさせるかどうか (indent_ctor_init_leading、indent_ctor_initと関連する) { true, false}
+indent_class_colon = true
+# コンストラクタのメンバーイニシャライザの先頭の':'の (仮想的な) インデント幅。 (indent_class_colon=trueの場合のみ) (デフォルト:2) { number }
+indent_ctor_init_leading = 4
+# コンストラクタのメンバーイニシャライザの残りのリストに対する追加インデント (indent_class_colon=trueの場合のみ) { number }
+indent_ctor_init = 0
+# 'else\nif'の'if'をインデントするかどうか { true, false }
+indent_else_if = false
+# '{'の後の行から始まる変数宣言のインデント幅の調整 (0: 調整なし、正値: カラム絶対値、負値: インデント相対値) { number }
+indent_var_def_blk = 0
+# 複数行に続く変数宣言を位置揃え (align) せずインデントする { true, false }
+indent_var_def_cont = false
+# 関数定義のインデントを行頭から強制的に開始するかどうか { true, false }
+indent_func_def_force_col1 = false
+# 複数行に続く関数コールの引数リストをインデントするか、位置揃えするか { true, false }
+indent_func_call_param = false
+# 複数行に続く関数定義の引数リストをインデントするか、位置揃えするか { true, false }
+indent_func_def_param = false
+# 複数行に続くプロトタイプ宣言の引数リストをインデントするか、位置揃えするか { true, false }
+indent_func_proto_param = false
+# 複数行に続くクラス宣言内のコンストラクタの引数リストをインデントするか、位置揃えするか { true, false }
+indent_func_class_param = false
+# 複数行に続くクラスコンストラクタコールの引数リストをインデントするか、位置揃えするか { true, false }
+indent_func_ctor_var_param = false
+# 複数行に続くテンプレートクラス宣言の引数リストをインデントするか、位置揃えするか { true, false }
+indent_template_param = false
+# indent_func_xxx_paramオプションのインデント幅を2倍にする { true, false }
+indent_func_param_double = false
+# 関数宣言/プロトタイプの単独でぶら下がる'const'修飾子の絶対カラム位置 { number }
+indent_func_const = 0
+# 関数宣言/プロトタイプの単独でぶら下がる'throw'修飾子の絶対カラム位置 { number }
+indent_func_throw = 0
+# '->'もしくは'.'に続く位置揃えの半角空白数 (通常は0) { number }
+indent_member = 0
+# コード直前にある、1行以上の一行コメント ('//') を位置揃えするための半角空白数 { number }
+indent_sing_line_comments = 0
+# コードの後ろに続く一行コメント ('//') を相対的にインデントするかどうか { true, false }
+indent_relative_single_line_comments = false
+# 'switch'から'case'をインデントする半角空白数 (通常は、0か、indent_columnsで設定した値) { number }
+indent_switch_case = 4
+# 'case'の中の他の行のインデントに影響を与えずに、'case'行だけを位置揃えするための半角空白数 (通常は0、インデント相対値) { number }
+indent_case_shift = 0
+# 'case'の'{'をインデントする半角空白数 (通常は0、インデント相対値) { number }
+indent_case_brace = 0
+# 行頭に見つけたコメントをインデントさせるかどうか { true, false }
+indent_col1_comment = true
+# gotoラベルのインデント方法 (正値: カラム絶対値、負値: インデント相対値) { number }
+indent_label = 1
+# コロンが続くアクセス指定子の場合 (正値: カラム絶対値、負値: インデント相対値) { number }
+indent_access_spec = -4
+# アクセス指定子の後のコードを1レベルインデントするかどうか (indent_access_specは0に強制的に上書きされる) { true, false }
+indent_access_spec_body = false
+# '('に続けて改行されている時、次行からは'('の後に整列するよう位置揃えする (非推奨) { true, false }
+indent_paren_nl = false
+# 改行後の')'のインデント方法 { 0: ボディレベルにインデントする 1: '('の位置に揃える 2: 直前の'{'レベルにインデントする }
+indent_paren_close = 0
+# '()'内の改行直後の','のインデント方法 (trueの場合、'('の直下に位置揃えされる) { true, false }
+indent_comma_paren = false
+# '()'内の改行直後のブール演算子のインデント方法 (trueの場合、'('の直下に位置揃えされる) { true, false }
+indent_bool_paren = false
+# indent_bool_paren=true時の、最初の評価式のインデント方法 (trueなら次の行以降と位置揃えする) { true, false }
+indent_first_bool_expr = false
+# '['に続けて改行されている時、次行からは'['の後に整列するよう位置揃えする (非推奨) { true, false }
+indent_square_nl = false
+# ESQL/Cの'EXEC SQL'ボディの相対インデントを変更しない { true, false }
+indent_preserve_sql = false
+# '='に続くステートメントをインデントするか、位置揃えするか (falseもしくは'='直後に改行場合、インデントする) { true, false }
+indent_align_assign = true
+# Objective-Cブロックを通常ルールの代わりブレースレベルまでインデントするかどうか { true, false }
+indent_oc_block = false
+# メッセージ内のObjective-Cブロックをパラメータ名に相対的にインデントする (0: indent_oc_blockルール >0: インデント半角空白数) { number }
+indent_oc_block_msg = 0
+# 継続するパラメータの最小インデント数 {number}
+indent_oc_msg_colon = 0
+
+### Alignment
+## http://qiita.com/items/aecf5d72a55eef7ed6fe
+# インデントではないタブ文字を残すか { true, false }
+align_keep_tabs = false
+# 整列位置合わせにタブ文字を利用するか { true, false }
+align_with_tabs = false
+# 整列位置合わせで次のタブストップ位置にするか { true, false }
+align_on_tabstop = false
+# 数値を左揃えにするかどうか (align_struct_init_spanと関連) { true, false }
+align_number_left = false
+# プロトタイプ宣言と関数定義で、変数定義の位置を揃えるかどうか { true, false }
+align_func_params = true
+# 同じ名前を持つシングルライン関数のパラメータの位置を揃えるかどうか (関数名はすでにそれぞれ位置合わせされていなければならない。) { true, false }
+align_same_func_call_params = false
+# 変数定義でのポインタの'*'の位置揃えの方法 { 0: 型の一部、1: 変数名の一部、2: ダングリング }
+align_var_def_star_style = 2
+# 変数定義での参照の'&'位置揃えの方法 { 0: 型の一部、1: 変数名の一部、2: ダングリング }
+align_var_def_amp_style = 2
+# 構造体ビットフィールドの':'を位置揃えするかどうか { true, false }
+align_var_def_colon = true
+# 変数名の後の属性を位置揃えするかどうか { true, false }
+align_var_def_attribute = true
+# struct/enum/unionのメンバ変数定義を位置揃えするかどうか { true, false }
+align_var_def_inline = true
+# 変数定義の位置揃えに対するラインスパン (0: 揃えない) { number }
+align_var_def_span = 1
+# 変数定義の位置揃えのカラム閾値 (0: 制限無し) { number }
+align_var_def_thresh = 0
+# 変数定義の位置揃えのカラムギャップ { number }
+align_var_def_gap = 0
+# 代入式の'='の位置揃えをするラインスパン (0: 揃えない) { number }
+align_assign_span = 1
+# 代入式の'='の位置揃えをするカラム閾値 (0: 制限無し) { number }
+align_assign_thresh = 0
+# enumの'='の位置揃えをするラインスパン (0: 揃えない) { number }
+align_enum_equ_span = 1
+# enumの'='の位置揃えをするカラム閾値 (0: 制限無し) { number }
+align_enum_equ_thresh = 0
+# struct/unionのメンバー定義の位置揃えをするラインスパン (0: 揃えない) { number }
+align_var_struct_span = 1
+# struct/unionのメンバー定義の位置揃えをするカラム閾値 (0: 制限無し) { number }
+align_var_struct_thresh = 0
+# struct/unionのメンバー定義のカラムギャップ { number }
+align_var_struct_gap = 0
+# structのメンバ変数の指定初期化の位置揃えのラインスパン (0: 揃えない) { number }
+align_struct_init_span = 1
+# typedefの型とシノニムの間の空白の最小数 { number }
+align_typedef_gap = 0
+# 一行typedefの位置揃えをするラインスパン (0: 揃えない) { number }
+align_typedef_span = 1
+# typedefされた関数とその他typedefの位置揃えの方法 { 0: ミックスして位置を揃えない、1: 開丸括弧と型の位置を揃える、2: 関数の型名とその他の型名の位置を揃える }
+align_typedef_func = 1
+# typedefの''の位置揃えの方法 { 0: typedef typeで揃える、1: ''を型名の一部とする、2: '*'を型名の一部としてダングリングする }
+align_typedef_star_style = 2
+# typedefの'&'の位置揃えの方法 { 0: typedef typeで揃える、1: '&'を型名の一部とする、2: '&'を型名の一部としてダングリングする }
+align_typedef_amp_style = 2
+# 行末コメントを位置揃えするラインスパン (0: 揃えない) { number }
+align_right_cmt_span = 1
+# If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment { true, false }
+align_right_cmt_mix = false
+# 行末コメントがこの桁数以上コードと離れている場合、位置揃えする (0: 揃えない) { number }
+align_right_cmt_gap = 1
+# 行末コメントの位置揃えするカラム位置 (嬉しい副産物 'pulls in' コメント) (0: 揃えない) { number }
+align_right_cmt_at_col = 0
+# プロトタイプ宣言の位置揃えのラインスパン (0: 揃えない) { number }
+align_func_proto_span = 2
+# プロトタイプ宣言の返値型と関数名の間のギャップカラム { number }
+align_func_proto_gap = 0
+# 'operator'キーワードでプロトタイプ宣言を位置揃えするかどうか { number }
+align_on_operator = true
+# プロトタイプと変数宣言のミックス整形するかどうか (trueの場合、align_var_def_XXXオプションがalign_func_proto_XXXオプションの代わりに使用される。) { true, false }
+align_mix_var_proto = false
+# 一行関数を関数プロトタイプと同様に位置揃えするかどうか (align_func_proto_spanを使用) { true, false }
+align_single_line_func = true
+# 一行関数のオープンブレースを位置揃えするかどうか (align_single_line_func=trueの場合のみ) (align_func_proto_spanを使用) { true, false }
+align_single_line_brace = true
+# align_single_line_braceに対するギャップ { number }
+align_single_line_brace_gap = 0
+# バックスラッシュ-改行で囲われた複数行マクロを位置揃えするかどうか (ただし、マクロが複数行コメントを内包している場合、うまく動かない) { true, false }
+align_nl_cont = true
+# プリプロセッサ定義のボディの位置揃えのスパン (0: 揃えない) { number }
+align_pp_define_span = 1
+# プリプロセッサ定義のラベルと値の間の空白の最小幅 { number }
+align_pp_define_gap = 0
+# マクロ関数とマクロ変数を一緒に位置揃えするかどうか { true, false }
+align_pp_define_together = false
+# '<<'で開始する行を前の行の'<<'の位置に揃えるかどうか (デフォルト: true) { true, false }
+align_left_shift = true
+# Objective-Cのメッセージ仕様宣言のスパン (0: 揃えない) { number }
+align_oc_msg_spec_span = 0
+# Objective-Cのメッセージコールにおけるパラメータ':'の位置揃えのスパン (0: 揃えない) { number }
+align_oc_msg_colon_span = 0
+# trueの場合、最初のパラメータの位置に後続パラメータの位置を揃える (メッセージが短くとも) { true, false }
+align_oc_msg_colon_first = false
+# Objective-Cの'+'もしくは'-'宣言行のパラメータを':'で位置揃えするかどうか { true, false }
+align_oc_decl_colon = false
+
+### Position
+## http://qiita.com/items/ce7269fe4aa9f34e9a8d
+# 式が折り返す時の算術演算子の位置 { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_arith = trail
+# 式が折り返す時の代入演算子の位置 '{'が続く'='には影響しない { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_assign = trail
+# 式が折り返す時のブール演算子の位置 { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_bool = trail
+# 式が折り返す時の比較演算子の位置 { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_compare = trail
+# 式が折り返す時の三項演算子 (b ? t : f) の位置 { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_conditional = ignore
+# 式が折り返す時の','の位置 { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_comma = trail
+# コンストラクタのメンバ初期化リストにおける','の位置 { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_class_comma = lead
+# コンストラクタとメンバ初期化の間の':'の位置 { ignore, join, lead, lead_break, lead_force, trail, trail_break, trail_force }
+pos_class_colon = lead
+
+### Break line
+## http://qiita.com/items/ee95487e79a2ca7fb375
+# 連続してもよい改行数。 (0: 制限なし) { number }
+nl_max = 0
+# 関数プロトタイプ宣言の後の改行数 (別のプロトタイプ宣言が続く場合) (0: 変更なし) { number }
+nl_after_func_proto = 1
+# 関数プロトタイプ宣言の後の改行数 (別のプロトタイプ宣言が続かない倍) { number }
+nl_after_func_proto_group = 2
+# 複数行の関数ボディの'}'の後の改行数 { number }
+nl_after_func_body = 2
+# クラス宣言内の複数行の関数ボディの'}'の後の改行数 { number }
+nl_after_func_body_class = 2
+# 一行関数ボディの'}'の後の改行数 { number }
+nl_after_func_body_one_liner = 1
+# 複数行コメントの前の最小改行数 ('{'もしくは別の複数行コメントの後の場合、適用されない。) { number }
+nl_before_block_comment = 0
+# 1行Cコメント ('/* ... */') の前の最小改行数 '{'もしくは別の1行Cコメントの後の場合、適用されない。 { number }
+nl_before_c_comment = 0
+# C++コメント ('// ...') の前の最小改行数 '{'もしくは別のC++コメントの後の場合、適用されない。 { number }
+nl_before_cpp_comment = 0
+# 複数行コメントの後に改行を強制するかどうか { false, true }
+nl_after_multiline_comment = true
+# struct/enum/unionの定義の'}'もしくは';'の後の改行数 { number }
+nl_after_struct = 2
+# class定義の'}'もしくは';'の後の改行数 { number }
+nl_after_class = 2
+# 'private:'、'public:'、'protected:'、'signals:'、'slots:'ラベルの前の改行数 '{'の後の場合、改行数は変更されない。 (0: 変更無し) { number }
+nl_before_access_spec = 1
+# 'private:'、'public:'、'protected:'、'signals:'、'slots:'ラベルの後の改行数 (0: 変更無し) { number }
+nl_after_access_spec = 1
+# 関数定義と関数コメントの間の改行数 (0: 変更無し) { number }
+nl_comment_func_def = 1
+# '}'が続かないtry-catch-finallyブロックの後の改行数 (0: 変更無し) { number }
+nl_after_try_catch_finally = 2
+# プロパティ、インデクサ、イベントの定義の前後の改行数 (0: 変更無し) { number }
+nl_around_cs_property = 0
+# get/set/add/removeハンドラの間の改行数 (C#言語) (0: 変更無し) { number }
+nl_between_get_set = 0
+# プロパティと'{'の間に改行を挿入/削除する (C#言語) { ignore, add, remove, force }
+nl_property_brace = ignore
+# '{'の後の改行を削除するかどうか { false, true }
+eat_blanks_after_open_brace = true
+# '}'の前の改行を削除するかどうか { false, true }
+eat_blanks_before_close_brace = true
+# プリプロセッサ以外の改行をどのぐらい積極的に削除するか 0: 変更しない 1: 他の設定でハンドルされない改行を可能な限り削除する 2: 全ての改行を一度削除して、設定から完全に整形しなおす { number }
+nl_remove_extra_newlines = 0
+# 'return'文の前に改行を挿入するかどうか ('{'直後の'return'以外) { false, true }
+nl_before_return = true
+# 'return'文の後に改行を挿入するかどうか ('}'が直後にある'return'以外) { false, true }
+nl_after_return = false
+# Java注釈文の後に改行を挿入するかどうか 改行後の注釈文にのみ適用される { ignore, add, remove, force }
+nl_after_annotation = ignore
+# 2つの注釈文の間に改行を挿入するかどうか { ignore, add, remove, force }
+nl_between_annotation = ignore
+# 関数宣言の')'と'{'の間に改行を挿入するかどうか { ignore, add, remove, force }
+nl_fdef_brace = force
+
+### Code transformation
+## http://qiita.com/items/d1289c116451b709f610
+# 単文の'do'/'while'文に'{}'を追加/削除する { ignore, add, remove, force }
+mod_full_brace_do = add
+# 単文の'for'文に'{}'を追加/削除する { ignore, add, remove, force }
+mod_full_brace_for = add
+# 単文の関数定義に'{}'を追加/削除する (Pawn) { ignore, add, remove, force }
+mod_full_brace_function = ignore
+# 単文の'if'文に'{}'を追加/削除する 'else'を含む場合、'{}'は削除されない。 { ignore, add, remove, force }
+mod_full_brace_if = add
+# 全ての'if'/'elseif'/'else'文のブロックを'{}'で囲うかどうか (1つでも'{}'で囲う必要があれば、全て'{}'で囲われ、全てが囲う必要がなければ、'{}'は削除される) { false, true } (mod_full_brace_ifを上書き)
+mod_full_brace_if_chain = false
+# mod_full_brace_xxxのボディがN行より長い場合、'{}'は削除しない { number }
+mod_full_brace_nl = 0
+# 単文の'while'文に'{}'を追加/削除する { ignore, add, remove, force }
+mod_full_brace_while = add
+# 単文の'using'文に'{}'を追加/削除する (C#言語) { ignore, add, remove, force }
+mod_full_brace_using = ignore
+# 'return'文の不要な'()'を追加/削除する { ignore, add, remove, force }
+mod_paren_on_return = remove
+# オプショナルなセミコロンをリアルなセミコロンに修正するかどうか (Pawn) { false, true }
+mod_pawn_semicolon = false
+# 'while'と'if'文のブール値の前後に括弧を追加する { false, true }
+mod_full_paren_if_bool = false
+# 余分なセミコロンを削除する { false, true }
+mod_remove_extra_semicolon = true
+# 関数ボディの行数が指定数を超えるような長い関数の場合、'}'の後にコメントが付く { number }
+mod_add_long_function_closebrace_comment = 0
+# 'switch'文のボディの行数が指定数を超えるような長いボディの場合、'}'の後にコメントが付く { number }
+mod_add_long_switch_closebrace_comment = 0
+# #ifdefのボディの行数が指定数を超えるような長いボディの場合、#endifの後にコメントが付く { number }
+mod_add_long_ifdef_endif_comment = 0
+# #ifdefもしくは#elseのボディが指定数を超えるような長いボディの場合、#elseの後にコメントが付く { number }
+mod_add_long_ifdef_else_comment = 0
+# 連続する1行の'import'文をソートするかどうか (Java言語、D言語) { false, true }
+mod_sort_import = false
+# 連続する1行の'using'文をソートするかどうか (C#言語) { false, true }
+mod_sort_using = false
+# 連続する1行の'#include'文もしくは'#import'文をソートするかどうか (Objective-C言語) コードを破壊する可能性があるので、一般的にソートしなおすのは良くない { false, true }
+mod_sort_include = false
+# '{}'で囲われた'case'の後にある'break'文を'}'の内側に移動する { false, true }
+mod_move_case_break = true
+# '{}'で囲われた'case'文の前後に'{}'を追加/削除する もし、ブロック内に変数宣言がない場合に限り、'{}'を削除できる { ignore, add, remove, force }
+mod_case_brace = ignore
+# 関数の最後の文に現れる、'return;'を削除するかどうか { false, true }
+mod_remove_empty_return = true
+
+### Comment transformation
+## http://qiita.com/items/cfeda8a49cf8efe48406
+# コメントを一定の幅で折り返す (桁数) { number }
+cmt_width = 240
+# コメントリフロー (テキストの流し込み、再配置) (0: 折り返しのみ (リフローしない) 1: リフローも折り返しもしない 2: フルリフロー) (0と2の差がわからない) { number }
+cmt_reflow_mode = 1
+# 複数行コメントの変更 (cmd_width、キーワード置換、先行文字列など含む) を無効化する { false, true }
+cmt_indent_multi = false
+# ブロックになっているCコメント ('/* ... */') をグループ化するかどうか { false, true }
+cmt_c_group = false
+# 結合したCコメントの最初の行に、'/*'単体を付けるかどうか { false, true }
+cmt_c_nl_start = false
+# 結合したCコメントの最後の行に、'*/'単体を付けるかどうか { false, true }
+cmt_c_nl_end = false
+# C++コメントをCコメントに変更するかどうか { false, true }
+cmt_cpp_to_c = false
+# ブロックになっているC++コメント ('// ....') をグループ化するかどうか (cmt_cpp_to_cがtrueの場合のみ) { false, true }
+cmt_cpp_group = false
+# 結合したC++コメント ('// ....') の最初の行に、'/*'単体を付けるかどうか (cmt_cpp_to_cがtrueの場合のみ) { false, true }
+cmt_cpp_nl_start = false
+# 結合したC++コメント ('// ....') の最後の行に、'*/'単体を付けるかどうか (cmt_cpp_to_cがtrueの場合のみ) { false, true }
+cmt_cpp_nl_end = false
+# コメント行にスター '*' を続けて付けるかどうか { false, true }
+cmt_star_cont = true
+# 連続するコメント行の開始位置と'*'の間に挿入する空白数 { number }
+cmt_sp_before_star_cont = 0
+# 連続するコメント行の'*'とコメントの間に挿入する空白数 { number }
+cmt_sp_after_star_cont = 0
+# '*'で始める複数行コメントに対し、最初と最後のコメント行が同じ長さの場合に、先頭にある空白を削除するかどうか (デフォルト: true) { false, true }
+cmt_multi_check_last = true
+
+### Line split
+## http://qiita.com/items/20a8143322e16d969ca8
+# コード幅の制限桁数 { number }
+code_width = 240
+# 長い'for'文を';'の位置でスプリットするかどうか { false, true }
+ls_for_split_full = true
+# 長い関数のプロトタイプ宣言/呼び出しを','の位置でスプリットするかどうか { false, true }
+ls_func_split_full = true
+# code_widthでスプリットするかどうか (だいたいcode_widthで少しはみ出す場合あり) { false, true }
+ls_code_width = true
+
+### Spacing
+## http://qiita.com/items/7b6564cebc60e26701f2
+# 算術演算子 '+'、'-'、'/'、'*'等の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_arith = add
+# 代入演算子 '='、'+='等の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_assign = add
+# C++11ラムダ式の外部変数キャプチャの'='演算子の前後に空白を挿入/削除する (sp_assignを上書き) { ignore, add, remove, force }
+sp_cpp_lambda_assign = ignore
+# C++11ラムダ式の変数キャプチャの']'と引数リストの'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_cpp_lambda_paren = remove
+# プロトタイプ宣言の'='の代入演算子の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_assign_default = remove
+# '='、'+='等の代入演算子の前に空白を挿入/削除する (sp_assignを上書き) { ignore, add, remove, force }
+sp_before_assign =add
+# '=', '+='等の代入演算子の後に空白を挿入/削除する (sp_assignを上書き) { ignore, add, remove, force }
+sp_after_assign = add
+# enumの'='代入演算子の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_enum_assign = add
+# enumの'='代入演算子の前に空白を挿入/削除する (sp_enum_assignを上書き) { ignore, add, remove, force }
+sp_enum_before_assign = add
+# enumの'='代入演算子の後に空白を挿入/削除する (sp_enum_assignを上書き) { ignore, add, remove, force }
+sp_enum_after_assign = add
+# プリプロセッサの'##'連結演算子の前後に空白を挿入/削除する (デフォルト: add) { ignore, add, remove, force }
+sp_pp_concat = add
+# プリプロセッサの'#'文字列化演算子の後に空白を挿入/削除する ('#@'文字化演算子にも適用される) { ignore, add, remove, force }
+sp_pp_stringify = remove
+# プリプロセッサの'#'文字列化演算子の前に空白を挿入/削除する (例: '#define x(y) L#y') { ignore, add, remove, force }
+sp_before_pp_stringify = ignore
+# '&&'と'||'の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_bool = add
+# '<'、'>'、'=='等の比較演算子の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_compare = add
+# '('と')'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_paren = remove
+# 入れ子の括弧の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_paren_paren = ignore
+# 入れ子の括弧の内側の空白の数を同じにするか、しないか { true,  false }
+sp_balance_nested_parens = false
+# ')'と'{'の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_paren_brace = ignore
+# ポインタの'*'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_ptr_star = add
+# 変数名が後に続かないポインタの'*'の前に空白を挿入/削除する 'ignore'の場合、sp_before_ptr_starが代わりに使用される。 { ignore, add, remove, force }
+sp_before_unnamed_ptr_star = add
+# ポインタの''と''の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_between_ptr_star = remove
+# 単語が続く場合、ポインタの'*'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_ptr_star = remove
+# 関数のプロトタイプ宣言や定義が続く場合、ポインタの'*'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_ptr_star_func = remove
+# (関数型の)開丸括弧が続く場合、ポインタの'*'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_ptr_star_paren = remove
+# 関数のプロトタイプ宣言や定義が続く場合、ポインタの'*'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_ptr_star_func = add
+# 参照の'&'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_byref = add
+# 変数名が後に続かない参照の'&'の前に空白を挿入/削除する 'ignore'の場合、spbefore_byrefが代わりに使用される。 { ignore, add, remove, force }
+sp_before_unnamed_byref = remove
+# 単語が続く場合、参照の'&'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_byref = remove
+# 関数のプロトタイプ宣言や定義が続く場合、参照の'&'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_byref_func = remove
+# 関数のプロトタイプ宣言や定義が続く場合、参照の'&'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_byref_func = add
+# 型と単語の間に空白を挿入/削除する (デフォルト: force) { ignore, add, remove, force }
+sp_after_type = force
+# D言語のテンプレート ('template Foo('と'class Foo(') において、丸括弧の前に空白を挿入/削除する { number }
+sp_before_template_paren = 0
+# 'template'と'<'の間に空白を挿入/削除する ignoreの場合、sp_before_angleが使用される。 { ignore, add, remove, force }
+sp_template_angle = force
+# '<>'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_angle = add
+# '<'と'>'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_angle = remove
+# '<>'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_angle = add
+# 'new List();'のように、'<>'と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_angle_paren = remove
+# 'List m;'のように、'<>'と単語の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_angle_word = add
+# '>>'の'>'と'>'の間に空白を挿入/削除する (C++/C#のテンプレート関連のみ) (デフォルト: add) { ignore, add, remove, force }
+sp_angle_shift = add
+# 'foo >'の'> >'の間の空白の削除を許可する (C++11のみ) (デフォルト: false) このオプションなしで、sp_angle_shiftは空白を削除できない。 { true, false }
+sp_permit_cpp11_shift = false
+# 'if'、'for'、'switch'、'while'の'('の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_sparen = add
+# if条件の'('と')'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_sparen = remove
+# if条件の')'の前に空白を挿入/削除する (sp_inside_sparenを上書き) { ignore, add, remove, force }
+sp_inside_sparen_close = remove
+# if条件の'('の後に空白を挿入/削除する (sp_inside_sparenを上書き) { ignore, add, remove, force }
+sp_inside_sparen_open = remove
+# 'if'、'for'、'switch'、'while'の')'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_sparen = add
+# 'if'、'for'、'switch'、'while'の')'と'{'の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_sparen_brace = add
+# 'invariant'と'('の間に空白を追加/削除する (D言語) { ignore, add, remove, force }
+sp_invariant_paren = ignore
+# 'invariant (C) c'の')'の後に空白を追加/削除する (D言語) { ignore, add, remove, force }
+sp_after_invariant_paren = ignore
+# 'if'、'for'、'while'と同じ行の';'のみの空のステートメントの前に空白を挿入/削除する { ignore, add, remove, force }
+sp_special_semi = add
+# ';'の前に空白を挿入/削除する (デフォルト: remove) { ignore, add, remove, force }
+sp_before_semi = remove
+# 空でない'for'文の';'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_semi_for = remove
+# 'for'文の空のパートの';'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_semi_for_empty = ignore
+# コメントが後に続く場合を除いて、';'の後の空白を挿入/削除する (デフォルト: add) { ignore, add, remove, force }
+sp_after_semi = add
+# 空でない'for'文の';'の後に空白を挿入/削除する (デフォルト: force) { ignore, add, remove, force }
+sp_after_semi_for = add
+# 'for'文の空のパートの最後のセミコロンの後に空白を挿入/削除する (for ( ; ; )) { ignore, add, remove, force }
+sp_after_semi_for_empty = ignore
+# '['の前に空白を挿入/削除する ('[]'以外) { ignore, add, remove, force }
+sp_before_square = remove
+# '[]'の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_squares = ignore
+# 空でない'['と']'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_square = ignore
+# ','の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_comma = add
+# ','の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_comma = remove
+# 開丸括弧とカンマの間に空白を挿入/削除する ('(,'と'( ,') { ignore, add, remove, force }
+sp_paren_comma = ignore
+# 可変パラメータの'...'の前に空白を挿入/削除する (非句点が先行している時) { ignore, add, remove, force }
+sp_before_ellipsis = add
+# 'class'の':'の後に空白を挿入/削除する { ignore, add, remove, force }
+# sp_after_class_colon = ignore
+# 'class'の':'の前に空白を挿入/削除する { ignore, add, remove, force }
+# sp_before_class_colon = ignore
+# 'case'の':'の前に空白を挿入/削除する (デフォルト: remove) { ignore, add, remove, force }
+sp_before_case_colon = remove
+# 'operator'と演算子記号の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_operator = remove
+# オペレータシンボルと開丸括弧の間に空白を挿入/削除する (operator ++()) { ignore, add, remove, force }
+sp_after_operator_sym = remove
+# キャストの後に空白を挿入/削除する (C言語/D言語) ('cast(int)a' vs 'cast(int) a'、'(int)a' vs '(int) a') { ignore, add, remove, force }
+sp_after_cast = add
+# キャストの括弧の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_paren_cast = remove
+# キャストの型と開丸括弧の間に空白を挿入/削除する (C++言語) ('int(exp)' vs 'int (exp)') { ignore, add, remove, force }
+sp_cpp_cast_paren = remove
+# 'sizeof'と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_sizeof_paren = remove
+# タグキーワードの後に空白を挿入/削除する (Pawn) { ignore, add, remove, force }
+sp_after_tag = ignore
+# enumの'{'と'}'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_braces_enum = add
+# struct/unionの'{'と'}'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_braces_struct = add
+# '{'と'}'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_braces = add
+# '{}'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_braces_empty = add
+# 戻り値の型と関数名の間に空白を挿入/削除する ポインタ型の戻り値を除いて、最低でも空白1文字が強制的に挿入される。 { ignore, add, remove, force }
+sp_type_func = add
+# 関数宣言の関数名と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_func_proto_paren = remove
+# 関数定義の関数名と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_func_def_paren = remove
+# 空の関数'()'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_fparens = remove
+# 関数の'('と')'の内側に空白を挿入/削除する { ignore, add, remove, force }
+sp_inside_fparen = remove
+# 関数タイプの最初の括弧の内側に空白を挿入/削除する ('void (*x)(...)') { ignore, add, remove, force }
+sp_inside_tparen = remove
+# 関数タイプの括弧どうしの間に空白を挿入/削除する ('void (*x)(...)') { ignore, add, remove, force }
+sp_after_tparen_close = remove
+# 関数コールパートで、']'と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_square_fparen = remove
+# 関数の')'と'{'の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_fparen_brace = add
+# 関数コールで関数名と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_func_call_paren = remove
+# パラメータなしの関数コールで関数名と'()'の間に空白を挿入/削除する 'ignore'の場合、sp_func_call_parenが使用される。 { ignore, add, remove, force }
+sp_func_call_paren_empty = remove
+# 関数コールでユーザ関数名と'('の間に空白を挿入/削除する 設定ファイルの中に'set func_call_user _'のように、ユーザ関数であることであるキーワードを設定する必要がある。 { ignore, add, remove, force }
+sp_func_call_user_paren = remove
+# コンストラクタ/デストラクタと開丸括弧の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_func_class_paren = remove
+# 'return'と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_return_paren = remove
+# 'attribute'と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_attribute_paren = remove
+# '#if defined (FOO)'の'defined'と'('の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_defined_paren = remove
+# 'throw'と'('の間に空白を挿入/削除する ('throw (something)') { ignore, add, remove, force }
+sp_throw_paren = add
+# 'throw'と'('以外の文字の間に空白を挿入/削除する ('@throw [...]') { ignore, add, remove, force }
+sp_after_throw = add
+# 'catch'と'('の間に空白を挿入/削除する ('catch (something) { }') ignoreの場合、sp_before_sparenが使用される。 { ignore, add, remove, force }
+sp_catch_paren = add
+# 'version'と'('の間に空白を挿入/削除する ('version (something) { }') (D言語) ignoreの場合、sp_before_sparenが使用される。 { ignore, add, remove, force }
+sp_version_paren = ignore
+# 'scope'と'('の間に空白を挿入/削除する ('scope (something) { }') (D言語) ignoreの場合、sp_before_sparenが使用される。 { ignore, add, remove, force }
+sp_scope_paren = ignore
+# マクロと値の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_macro = add
+# マクロ関数の')'と値の間に空白を挿入/削除する { ignore, add, remove, force }
+sp_macro_func = add
+# 一行に'else'と'{'がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_else_brace = add
+# 一行に'}'と'else'がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_brace_else = add
+# 一行に'}'とtypedefの型名がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_brace_typedef = add
+# 一行に'catch'と'{'がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_catch_brace = add
+# 一行に'}'と'catch'がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_brace_catch = add
+# 一行に'finally'と'{'がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_finally_brace = add
+# 一行に'}'と'finally'がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_brace_finally = add
+# 一行に'try'と'{'がある場合、間に空白を挿入/削除する { ignore, add, remove, force }
+sp_try_brace = add
+# 一行に'get'/'set'と'{'がある場合、間に空白を挿入/削除する { false, true }
+sp_getset_brace = add
+# '::'演算子の前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_dc = remove
+# '::'演算子の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_dc = remove
+# 名前付き配列イニシャライザ':'の前後に空白を挿入/削除する (D言語) { ignore, add, remove, force }
+sp_d_array_colon = ignore
+# '!' (not) 演算子の後に空白を挿入/削除する (デフォルト: remove) { ignore, add, remove, force }
+sp_not = remove
+# '~' (invert) 演算子の後に空白を挿入/削除する (デフォルト: remove) { ignore, add, remove, force }
+sp_inv = remove
+# アドレス演算子'&'の後に空白を挿入/削除する (デフォルト: remove) 参照型の一部である'&'の後のスペーシングには影響しない。 { ignore, add, remove, force }
+sp_addr = remove
+# '.'や'->'演算子の前後に空白を挿入/削除する (デフォルト: remove) { ignore, add, remove, force }
+sp_member = remove
+# '' (dereference) 演算子の後に空白を挿入/削除する (デフォルト: remove) ポインタ型の一部である''の後のスペーシングには影響しない。 { ignore, add, remove, force }
+sp_deref = remove
+# 単項演算子'+'、'-'の後に空白を挿入/削除する ('x = -5'、'y = +7') (デフォルト: remove) { ignore, add, remove, force }
+sp_sign = remove
+# 単項演算子'++'、'--'の後に空白を挿入/削除する ('(--x)'、'y++;') (デフォルト: remove) { ignore, add, remove, force }
+sp_incdec = remove
+# 行末のバックスラッシュ('\')-改行の前に空白を挿入/削除する (デフォルト: add) { ignore, add, remove, force }
+sp_before_nl_cont = add
+# スコープ定義'+'、'-'の後に空白を挿入/削除する ('-(void) foo;'、'+(int) bar;') (Objective-C言語) { ignore, add, remove, force }
+sp_after_oc_scope = add
+# メッセージ仕様宣言の':'の後に空白を挿入/削除する (Objective-C言語) ('-(int) f:(int) x;' vs '-(int) f: (int) x;') { ignore, add, remove, force }
+sp_after_oc_colon = remove
+# メッセージ仕様宣言の':'の前に空白を挿入/削除する (Objective-C言語) ('-(int) f: (int) x;' vs '-(int) f : (int) x;') { ignore, add, remove, force }
+sp_before_oc_colon = remove
+# 不変ディクショナリ式における':'の後に空白を挿入/削除する (Objective-C言語) ('NSDictionary *test = @{@"foo" :@"bar"};') { ignore, add, remove, force }
+sp_after_oc_dict_colon = add
+# 不変ディクショナリ式における':'の前に空白を挿入/削除する (Objective-C言語) ('NSDictionary *test = @{@"foo" :@"bar"};') { ignore, add, remove, force }
+sp_before_oc_dict_colon = remove
+# メッセージ送信式の':'の後に空白を挿入/削除する (Objective-C言語) ('[object setValue:1];' vs '[object setValue: 1];') { ignore, add, remove, force }
+sp_after_send_oc_colon = remove
+# メッセージ送信式の':'の前に空白を挿入/削除する (Objective-C言語) ('[object setValue:1];' vs '[object setValue :1];') { ignore, add, remove, force }
+sp_before_send_oc_colon = remove
+# メッセージ仕様宣言の(type)の後に空白を挿入/削除する (Objective-C言語) ('-(int)f: (int) x;' vs '-(int)f: (int)x;') { ignore, add, remove, force }
+sp_after_oc_type = remove
+# メッセージ仕様宣言の最初の(type)の後に空白を挿入/削除する (Objective-C言語) ('-(int) f:(int)x;' vs '-(int)f:(int)x;') { ignore, add, remove, force }
+sp_after_oc_return_type = remove
+# '@selector'と'('の間に空白を挿入/削除する (Objective-C言語) ('@selector(msgName)' vs '@selector (msgName)') 同時に@protocol()ブロックにも提供される。 { ignore, add, remove, force }
+sp_after_oc_at_sel = remove
+# '@selector(x)'と続く単語の間に空白を挿入/削除する (Objective-C言語) ('@selector(foo) a:' vs '@selector(foo)a:') { ignore, add, remove, force }
+sp_after_oc_at_sel_parens = add
+# '@selector'の丸括弧の内側に空白を挿入/削除する (Objective-C言語) ('@selector(foo)' vs '@selector( foo )') Also applies to @protocol() constructs { false, true }
+sp_inside_oc_at_sel_parens = remove
+# ブロックポインタのキャレットの前に空白を挿入/削除する (Objective-C言語) ('^int (int arg){...}' vs. ' ^int (int arg){...}') { ignore, add, remove, force }
+sp_before_oc_block_caret = remove
+# ブロックポインタのキャレットの後に空白を挿入/削除する (Objective-C言語) ('^int (int arg){...}' vs. '^ int (int arg){...}') { ignore, add, remove, force }
+sp_after_oc_block_caret = remove
+# メッセージ内のレシーバとセレクタの間に空白を挿入/削除する (Objective-C言語) { ignore, add, remove, force }
+sp_after_oc_msg_receiver = add
+# @propertyの後に空白を挿入/削除する (Objective-C言語) { ignore, add, remove, force }
+sp_after_oc_property = add
+# 三項演算子の':'の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_cond_colon = add
+# 三項演算子の'?'の前後に空白を挿入/削除する { ignore, add, remove, force }
+sp_cond_question = add
+# 'case'とケースラベルの間のスペーシングを固定する ('ignore'と'force'のみ有効) { ignore, add, remove, force }
+sp_case_label = add
+# '..'演算子の前後に空白を挿入/削除する (D言語) { ignore, add, remove, force }
+sp_range = ignore
+# 'for'分の':'の後に空白を挿入/削除する ('for (TYPE VAR : EXPR)') (Java言語) { ignore, add, remove, force }
+sp_after_for_colon = add
+# 'for'分の':'の前に空白を挿入/削除する ('for (TYPE VAR : EXPR)') (Java言語) { ignore, add, remove, force }
+sp_before_for_colon = add
+# 'extern (C)'の'extern'と'('の間に空白を挿入/削除する (D言語) { ignore, add, remove, force }
+sp_extern_paren = ignore
+# C++コメントの開始の後に空白を挿入/削除する ('// A' vs '//A') { ignore, add, remove, force }
+sp_cmt_cpp_start = add
+# '#else'もしくは'#endif'とそれに続くコメントの間に空白を挿入/削除する { ignore, add, remove, force }
+sp_endif_cmt = add
+# 'new'、'delete'、'delete[]'の後に空白を挿入/削除する { ignore, add, remove, force }
+sp_after_new = add
+# 行末コメントもしくは文中コメントの前に空白を挿入/削除する { ignore, add, remove, force }
+sp_before_tr_emb_cmt = add
+# 行末コメントもしくは文中コメントの前に挿入する空白の数 { ignore, add, remove, force }
+sp_num_before_tr_emb_cmt = 0
+# Javaアノテーションと開丸括弧の間に空白を挿入/削除する (Java言語) { ignore, add, remove, force }
+sp_annotation_paren = ignore
\ No newline at end of file
[from now] 2013/11/19 18:49:44

diff --git a/.emacs.d/elisp/php-mode.el b/.emacs.d/elisp/php-mode.el
new file mode 100644
index 0000000..0feb57c
--- /dev/null
+++ b/.emacs.d/elisp/php-mode.el
@@ -0,0 +1,1911 @@
+;;; php-mode.el --- Major mode for editing PHP code
+
+;; Copyright (C) 1999, 2000, 2001, 2003, 2004 Turadg Aleahmad
+;;               2008 Aaron S. Hawley
+;;               2011, 2012, 2013 Eric James Michael Ritz
+
+;;; Author: Eric James Michael Ritz
+;;; URL: https://github.com/ejmr/php-mode
+;;; Version: 1.12
+
+(defconst php-mode-version-number "1.12"
+  "PHP Mode version number.")
+
+(defconst php-mode-modified "2013-10-29"
+  "PHP Mode build date.")
+
+;;; License
+
+;; This file is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 3
+;; of the License, or (at your option) any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Usage
+
+;; Put this file in your Emacs lisp path (eg. site-lisp) and add to
+;; your .emacs file:
+;;
+;;   (require 'php-mode)
+
+;; To use abbrev-mode, add lines like this:
+;;   (add-hook 'php-mode-hook
+;;     '(lambda () (define-abbrev php-mode-abbrev-table "ex" "extends")))
+
+;; To make php-mode compatible with html-mode, see http://php-mode.sf.net
+
+;; Many options available under Help:Customize
+;; Options specific to php-mode are in
+;;  Programming/Languages/Php
+;; Since it inherits much functionality from c-mode, look there too
+;;  Programming/Languages/C
+
+;;; Commentary:
+
+;; PHP mode is a major mode for editing PHP source code.  It's an
+;; extension of C mode; thus it inherits all C mode's navigation
+;; functionality.  But it colors according to the PHP grammar and
+;; indents according to the PEAR coding guidelines.  It also includes
+;; a couple handy IDE-type features such as documentation search and a
+;; source and class browser.
+
+;;; Code:
+
+(require 'add-log)
+(require 'font-lock)
+(require 'cc-mode)
+(require 'cc-langs)
+(require 'custom)
+(require 'flymake)
+(require 'etags)
+(require 'speedbar)
+(eval-when-compile
+  (unless (require 'cl-lib nil t)
+    (require 'cl))
+  (require 'regexp-opt)
+  (defvar c-vsemi-status-unknown-p)
+  (defvar syntax-propertize-via-font-lock))
+
+;;; Emacs 24.3 obsoletes flet in favor of cl-flet.  So if we are not
+;;; using that version then we revert to using flet.
+(unless (fboundp 'cl-flet)
+  (defalias 'cl-flet 'flet))
+
+;; Local variables
+;;;###autoload
+(defgroup php nil
+  "Major mode `php-mode' for editing PHP code."
+  :prefix "php-"
+  :group 'languages
+  :link '(url-link :tag "Official Site" "https://github.com/ejmr/php-mode")
+  :link '(url-link :tag "PHP Mode Wiki" "https://github.com/ejmr/php-mode/wiki"))
+
+(defcustom php-executable "/usr/bin/php"
+  "The location of the PHP executable."
+  :type 'string
+  :group 'php)
+
+(defcustom php-default-face 'default
+  "Default face in `php-mode' buffers."
+  :type 'face
+  :group 'php)
+
+(defcustom php-function-call-face 'default
+  "Default face for function calls in `php-mode' buffers."
+  :type 'face
+  :group 'php)
+
+(defcustom php-speedbar-config t
+  "When set to true automatically configures Speedbar to observe PHP files.
+Ignores php-file patterns option; fixed to expression \"\\.\\(inc\\|php[s345]?\\)\""
+  :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (when val
+             (speedbar-add-supported-extension
+              "\\.\\(inc\\|php[s345]?\\|phtml\\)")))
+  :group 'php)
+
+(defcustom php-mode-speedbar-open nil
+  "Normally `php-mode' starts with the speedbar closed.
+Turning this on will open it whenever `php-mode' is loaded."
+  :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (when val
+             (speedbar 1)))
+  :group 'php)
+
+(defcustom php-template-compatibility t
+  "Should detect presence of html tags."
+  :type 'boolean
+  :group 'php)
+
+;;;###autoload
+(defcustom php-extra-constants '()
+  "A list of additional strings to treat as PHP constants."
+  :type 'list
+  :group 'php)
+
+(defun php-create-regexp-for-method (visibility)
+  "Make a regular expression for methods with the given VISIBILITY.
+
+VISIBILITY must be a string that names the visibility for a PHP
+method, e.g. 'public'.  The parameter VISIBILITY can itself also
+be a regular expression.
+
+The regular expression this function returns will check for other
+keywords that can appear in method signatures, e.g. 'final' and
+'static'.  The regular expression will have one capture group
+which will be the name of the method."
+  (concat
+   ;; Initial space with possible 'abstract' or 'final' keywords
+   "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?"
+   ;; The function visilibity
+   visibility
+   ;; Is it static?
+   "\\s-+\\(?:static\\s-+\\)?"
+   ;; Make sure 'function' comes next with some space after
+   "function\\s-+"
+   ;; Capture the name as the first group and the regexp and make sure
+   ;; by the end we see the opening parenthesis for the parameters.
+   "\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*("))
+
+(defun php-create-regexp-for-classlike (type)
+  "Accepts a `type' of a 'classlike' object as a string, such as
+'class' or 'interface', and returns a regexp as a string which
+can be used to match against definitions for that classlike."
+  (concat
+   ;; First see if 'abstract' or 'final' appear, although really these
+   ;; are not valid for all values of `type' that the function
+   ;; accepts.
+   "^\\s-*\\(?:\\(?:abstract\\|final\\)\\s-+\\)?"
+   ;; The classlike type
+   type
+   ;; Its name, which is the first captured group in the regexp.  We
+   ;; allow backslashes in the name to handle namespaces, but again
+   ;; this is not necessarily correct for all values of `type'.
+   "\\s-+\\(\\(?:\\sw\\|\\\\\\|\\s_\\)+\\)"))
+
+(defvar php-imenu-generic-expression
+  `(("Namespaces"
+    ,(php-create-regexp-for-classlike "namespace") 1)
+   ("Classes"
+    ,(php-create-regexp-for-classlike "class") 1)
+   ("Interfaces"
+    ,(php-create-regexp-for-classlike "interface") 1)
+   ("Traits"
+    ,(php-create-regexp-for-classlike "trait") 1)
+   ("All Methods"
+    ,(php-create-regexp-for-method "\\(?:\\sw\\|\\s_\\)+") 1)
+   ("Private Methods"
+    ,(php-create-regexp-for-method "private") 1)
+   ("Protected Methods"
+    ,(php-create-regexp-for-method "protected")  1)
+   ("Public Methods"
+    ,(php-create-regexp-for-method "public") 1)
+   ("Anonymous Functions"
+    "\\<\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*=\\s-*function\\s-*(" 1)
+   ("Named Functions"
+    "^\\s-*function\\s-+\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" 1))
+ "Imenu generic expression for PHP Mode. See `imenu-generic-expression'.")
+
+(defcustom php-manual-url "http://www.php.net/manual/en/"
+  "URL at which to find PHP manual.
+You can replace \"en\" with your ISO language code."
+  :type 'string
+  :group 'php)
+
+(defcustom php-search-url "http://www.php.net/"
+  "URL at which to search for documentation on a word."
+  :type 'string
+  :group 'php)
+
+(defcustom php-completion-file ""
+  "Path to the file which contains the function names known to PHP."
+  :type 'string
+  :group 'php)
+
+(defcustom php-manual-path ""
+  "Path to the directory which contains the PHP manual."
+  :type 'string
+  :group 'php)
+
+;;;###autoload
+(add-to-list 'interpreter-mode-alist (cons "php" 'php-mode))
+
+(defcustom php-mode-hook nil
+  "List of functions to be executed on entry to `php-mode'."
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-pear-hook nil
+  "Hook called when a PHP PEAR file is opened with `php-mode'."
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-drupal-hook nil
+  "Hook called when a Drupal file is opened with `php-mode'."
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-wordpress-hook nil
+  "Hook called when a WordPress file is opened with `php-mode'."
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-symfony2-hook nil
+  "Hook called when a Symfony2 file is opened with `php-mode'."
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-force-pear nil
+  "Normally PEAR coding rules are enforced only when the filename contains \"PEAR.\"
+Turning this on will force PEAR rules on all PHP files."
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-mode-warn-if-mumamo-off t
+  "Warn once per buffer if you try to indent a buffer without
+mumamo-mode turned on. Detects if there are any HTML tags in the
+buffer before warning, but this is is not very smart; e.g. if you
+have any tags inside a PHP string, it will be fooled."
+  :type '(choice (const :tag "Warg" t) (const "Don't warn" nil))
+  :group 'php)
+
+(defcustom php-mode-coding-style 'pear
+  "Select default coding style to use with php-mode.
+This variable can take one of the following symbol values:
+
+`PEAR' - use coding styles preferred for PEAR code and modules.
+
+`Drupal' - use coding styles preferred for working with Drupal projects.
+
+`WordPress' - use coding styles preferred for working with WordPress projects.
+
+`Symfony2' - use coding styles preferred for working with Symfony2 projects."
+  :type '(choice (const :tag "PEAR" pear)
+                 (const :tag "Drupal" drupal)
+                 (const :tag "WordPress" wordpress)
+                 (const :tag "Symfony2" symfony2))
+  :group 'php
+  :set 'php-mode-custom-coding-style-set
+  :initialize 'custom-initialize-default)
+
+(defun php-mode-custom-coding-style-set (sym value)
+  (when (eq major-mode 'php-mode)
+    (set         sym value)
+    (set-default sym value)
+    (cond ((eq value 'pear)
+           (php-enable-pear-coding-style))
+          ((eq value 'drupal)
+           (php-enable-drupal-coding-style))
+          ((eq value 'wordpress)
+           (php-enable-wordpress-coding-style))
+          ((eq value 'symfony2)
+           (php-enable-symfony2-coding-style)))))
+
+
+
+(c-add-style
+ "pear"
+ '((c-basic-offset . 4)
+   (c-offsets-alist . ((block-open . -)
+                       (block-close . 0)
+                       (topmost-intro-cont . (first c-lineup-cascaded-calls
+                                                    php-lineup-arglist-intro))
+                       (brace-list-intro . +)
+                       (brace-list-entry . c-lineup-cascaded-calls)
+                       (arglist-close . php-lineup-arglist-close)
+                       (arglist-intro . php-lineup-arglist-intro)
+                       (knr-argdecl . [0])
+                       (arglist-cont-nonempty . c-lineup-cascaded-calls)
+                       (statement-cont . (first c-lineup-cascaded-calls +))))))
+
+(defun php-enable-pear-coding-style ()
+  "Sets up php-mode to use the coding styles preferred for PEAR
+code and modules."
+  (interactive)
+  (setq tab-width 4
+        indent-tabs-mode nil)
+  (c-set-style "pear"))
+
+(c-add-style
+ "drupal"
+ '((c-basic-offset . 2)
+   (c-offsets-alist . ((case-label . +)
+                       (topmost-intro-cont . (first c-lineup-cascaded-calls
+                                                    php-lineup-arglist-intro))
+                       (brace-list-intro . +)
+                       (brace-list-entry . c-lineup-cascaded-calls)
+                       (arglist-close . php-lineup-arglist-close)
+                       (arglist-intro . php-lineup-arglist-intro)
+                       (arglist-cont-nonempty . (first c-lineup-math c-lineup-cascaded-calls))
+                       (knr-argdecl . [0])
+                       (statement-cont . (first c-lineup-cascaded-calls +))))))
+
+(defun php-enable-drupal-coding-style ()
+  "Makes php-mode use coding styles that are preferable for
+working with Drupal."
+  (interactive)
+  (setq tab-width 2
+        indent-tabs-mode nil
+        fill-column 78
+        show-trailing-whitespace t)
+  (add-hook 'before-save-hook 'delete-trailing-whitespace)
+  (c-set-style "drupal"))
+
+(c-add-style
+ "wordpress"
+ '((c-basic-offset . 4)
+   (c-offsets-alist . ((arglist-cont . 0)
+                       (arglist-intro . php-lineup-arglist-intro)
+                       (arglist-close . php-lineup-arglist-close)
+                       (topmost-intro-cont . (first c-lineup-cascaded-calls
+                                                    php-lineup-arglist-intro))
+                       (brace-list-intro . +)
+                       (brace-list-entry . c-lineup-cascaded-calls)
+                       (case-label . 2)
+                       (arglist-close . 0)
+                       (defun-close . 0)
+                       (defun-block-intro . +)
+                       (knr-argdecl . [0])
+                       (arglist-cont-nonempty . c-lineup-cascaded-calls)
+                       (statement-cont . (first c-lineup-cascaded-calls +))))))
+
+(defun php-enable-wordpress-coding-style ()
+  "Makes php-mode use coding styles that are preferable for
+working with Wordpress."
+  (interactive)
+  (setq indent-tabs-mode t
+        fill-column 78
+        tab-width 4
+        c-indent-comments-syntactically-p t)
+  (c-set-style "wordpress"))
+
+(c-add-style
+ "symfony2"
+ '((c-basic-offset . 4)
+   (c-offsets-alist . ((arglist-cont . php-lineup-arglist)
+                       (arglist-intro . php-lineup-arglist-intro)
+                       (arglist-close . php-lineup-arglist-close)
+                       (topmost-intro-cont . (first c-lineup-cascaded-calls
+                                                    php-lineup-arglist-intro))
+                       (brace-list-intro . +)
+                       (brace-list-entry . c-lineup-cascaded-calls)
+                       (case-label . 4)
+                       (statement-case-intro . 4)
+                       (defun-close . 0)
+                       (defun-block-intro . +)
+                       (knr-argdecl . [0])
+                       (arglist-cont-nonempty . c-lineup-cascaded-calls)
+                       (statement-cont . php-lineup-hanging-semicolon)))))
+
+(defun php-enable-symfony2-coding-style ()
+  "Makes php-mode use coding styles that are preferable for
+working with Symfony2."
+  (interactive)
+  (setq indent-tabs-mode nil
+        fill-column 78
+        tab-width 4
+        c-indent-comments-syntactically-p t
+        require-final-newline t)
+  (c-set-style "symfony2"))
+
+
+(defun php-mode-version ()
+  "Display string describing the version of PHP mode."
+  (interactive)
+  (message "PHP mode %s of %s"
+           php-mode-version-number php-mode-modified))
+
+(defconst php-beginning-of-defun-regexp
+  "^\\s-*\\(?:\\(?:abstract\\|final\\|private\\|protected\\|public\\|static\\)\\s-+\\)*function\\s-+&?\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*("
+  "Regular expression for a PHP function.")
+
+(defun php-beginning-of-defun (&optional arg)
+  "Move to the beginning of the ARGth PHP function from point.
+Implements PHP version of `beginning-of-defun-function'."
+  (interactive "p")
+  (let ((arg (or arg 1)))
+    (while (> arg 0)
+      (re-search-backward php-beginning-of-defun-regexp
+                          nil 'noerror)
+      (setq arg (1- arg)))
+    (while (< arg 0)
+      (end-of-line 1)
+      (let ((opoint (point)))
+        (beginning-of-defun 1)
+        (forward-list 2)
+        (forward-line 1)
+        (if (eq opoint (point))
+            (re-search-forward php-beginning-of-defun-regexp
+                               nil 'noerror))
+        (setq arg (1+ arg))))))
+
+(defun php-end-of-defun (&optional arg)
+  "Move the end of the ARGth PHP function from point.
+Implements PHP befsion of `end-of-defun-function'
+
+See `php-beginning-of-defun'."
+  (interactive "p")
+  (php-beginning-of-defun (- (or arg 1))))
+
+
+(defvar php-warned-bad-indent nil)
+
+;; Do it but tell it is not good if html tags in buffer.
+(defun php-check-html-for-indentation ()
+  (let ((html-tag-re "^\\s-*</?\\sw+.*?>")
+        (here (point)))
+    (goto-char (line-beginning-position))
+    (if (or (when (boundp 'mumamo-multi-major-mode) mumamo-multi-major-mode)
+            ;; Fix-me: no idea how to check for mmm or multi-mode
+            (save-match-data
+              (not (or (re-search-forward html-tag-re (line-end-position) t)
+                       (re-search-backward html-tag-re (line-beginning-position) t)))))
+        (progn
+          (goto-char here)
+          t)
+      (goto-char here)
+      (setq php-warned-bad-indent t)
+      (let* ((known-multi-libs '(("mumamo" mumamo (lambda () (nxhtml-mumamo)))
+                                 ("mmm-mode" mmm-mode (lambda () (mmm-mode 1)))
+                                 ("multi-mode" multi-mode (lambda () (multi-mode 1)))))
+             (known-names (mapcar (lambda (lib) (car lib)) known-multi-libs))
+             (available-multi-libs (delq nil
+                                         (mapcar
+                                          (lambda (lib)
+                                            (when (locate-library (car lib)) lib))
+                                          known-multi-libs)))
+             (available-names (mapcar (lambda (lib) (car lib)) available-multi-libs))
+             (base-msg
+              (concat
+               "Indentation fails badly with mixed HTML/PHP in the HTML part in
+plain `php-mode'.  To get indentation to work you must use an
+Emacs library that supports 'multiple major modes' in a buffer.
+Parts of the buffer will then be in `php-mode' and parts in for
+example `html-mode'.  Known such libraries are:\n\t"
+               (mapconcat 'identity known-names ", ")
+               "\n"
+               (if available-multi-libs
+                   (concat
+                    "You have these available in your `load-path':\n\t"
+                    (mapconcat 'identity available-names ", ")
+                    "\n\n"
+                    "Do you want to turn any of those on? ")
+                 "You do not have any of those in your `load-path'.")))
+             (is-using-multi
+              (catch 'is-using
+                (dolist (lib available-multi-libs)
+                  (when (and (boundp (cadr lib))
+                             (symbol-value (cadr lib)))
+                    (throw 'is-using t))))))
+        (unless is-using-multi
+          (if available-multi-libs
+              (if (not (y-or-n-p base-msg))
+                  (message "Did not do indentation, but you can try again now if you want")
+                (let* ((name
+                        (if (= 1 (length available-multi-libs))
+                            (car available-names)
+                          ;; Minibuffer window is more than one line, fix that first:
+                          (message "")
+                          (completing-read "Choose multiple major mode support library: "
+                                           available-names nil t
+                                           (car available-names)
+                                           '(available-names . 1)
+                                           )))
+                       (mode (when name
+                               (caddr (assoc name available-multi-libs)))))
+                  (when mode
+                    ;; Minibuffer window is more than one line, fix that first:
+                    (message "")
+                    (load name)
+                    (funcall mode))))
+            (lwarn 'php-indent :warning base-msg)))
+        nil))))
+
+(defun php-cautious-indent-region (start end &optional quiet)
+  (if (or (not php-mode-warn-if-mumamo-off)
+          php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (funcall 'c-indent-region start end quiet)))
+
+(defun php-cautious-indent-line ()
+  (if (or (not php-mode-warn-if-mumamo-off)
+          php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (let ((here (point))
+            doit)
+        (move-beginning-of-line nil)
+        ;; Don't indent heredoc end mark
+        (save-match-data
+          (unless (looking-at "[a-zA-Z0-9_]+;\n")
+            (setq doit t)))
+        (goto-char here)
+        (when doit
+          (funcall 'c-indent-line)))))
+
+(defconst php-tags '("<?php" "?>" "<?" "<?="))
+(defconst php-tags-key (regexp-opt php-tags))
+
+(defconst php-block-stmt-1-kwds '("do" "else" "finally" "try"))
+(defconst php-block-stmt-2-kwds
+  '("for" "if" "while" "switch" "foreach" "elseif" "catch" "catch all"))
+
+(defconst php-block-stmt-1-key
+  (regexp-opt php-block-stmt-1-kwds))
+(defconst php-block-stmt-2-key
+  (regexp-opt php-block-stmt-2-kwds))
+
+(defconst php-class-decl-kwds '("class" "interface" "trait" "namespace"))
+
+(defconst php-class-key
+  (concat
+   "\\(" (regexp-opt php-class-decl-kwds) "\\)\\s-+"
+   (c-lang-const c-symbol-key c)                ;; Class name.
+   "\\(\\s-+extends\\s-+" (c-lang-const c-symbol-key c) "\\)?" ;; Name of superclass.
+   "\\(\\s-+implements\\s-+[^{]+{\\)?")) ;; List of any adopted protocols.
+
+
+(defun php-c-at-vsemi-p (&optional pos)
+  "Return t on html lines (including php region border), otherwise nil.
+POS is a position on the line in question.
+
+This is was done due to the problem reported here:
+
+  URL `https://answers.launchpad.net/nxhtml/+question/43320'"
+  (if (not php-template-compatibility)
+      nil
+    (setq pos (or pos (point)))
+    (let ((here (point))
+          ret)
+      (save-match-data
+        (goto-char pos)
+        (beginning-of-line)
+        (setq ret (looking-at
+                   (rx
+                    (or (seq
+                         bol
+                         (0+ space)
+                         "<"
+                         (in "a-z\\?"))
+                        (seq
+                         (0+ not-newline)
+                         (in "a-z\\?")
+                         ">"
+                         (0+ space)
+                         eol))))))
+      (goto-char here)
+      ret)))
+
+(defun php-c-vsemi-status-unknown-p ()
+  "See `php-c-at-vsemi-p'."
+  )
+
+(defun php-lineup-arglist-intro (langelem)
+  (save-excursion
+    (goto-char (cdr langelem))
+    (vector (+ (current-column) c-basic-offset))))
+
+(defun php-lineup-arglist-close (langelem)
+  (save-excursion
+    (goto-char (cdr langelem))
+    (vector (current-column))))
+
+(c-set-offset 'arglist-intro 'php-lineup-arglist-intro)
+(c-set-offset 'arglist-close 'php-lineup-arglist-close)
+
+(defun php-lineup-arglist (langelem)
+  (save-excursion
+    (beginning-of-line)
+    (if (looking-at-p "\\s-*->") '+ 0)))
+
+(defun php-lineup-hanging-semicolon (langelem)
+  (save-excursion
+    (beginning-of-line)
+    (if (looking-at-p "\\s-*;\\s-*$") 0 '+)))
+
+;;; We silence all byte-compiler warnings when creating the `syntax'
+;;; variable binding in this function.  Emacs will normally warn us
+;;; that `c-syntactic-context' is unbound.  The variable comes from CC
+;;; Mode and it is only bound dynamically when calling certain
+;;; indentation functions.  See the documentation in section "8.1.1
+;;; Custom Brace Hanging" of the CC Mode manual for more information,
+;;; along with an explanation of why we do not simply bind the
+;;; variable to a value in order to appease the compiler warning.
+(defun php-unindent-closure ()
+  (let ((syntax (with-no-warnings (mapcar 'car c-syntactic-context))))
+    (if (and (member 'arglist-cont-nonempty syntax)
+             (or
+              (member 'statement-block-intro syntax)
+              (member 'brace-list-intro syntax)
+              (member 'brace-list-close syntax)
+              (member 'block-close syntax)))
+        (save-excursion
+          (let ((count-func (if (fboundp 'cl-count) #'cl-count #'count)))
+            (beginning-of-line)
+            (delete-char (* (funcall count-func 'arglist-cont-nonempty syntax)
+                            c-basic-offset)))))))
+
+(defvar php-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [menu-bar php]
+      (cons "PHP" (make-sparse-keymap "PHP")))
+
+    (define-key map [menu-bar php complete-function]
+      '("Complete function name" . php-complete-function))
+    (define-key map [menu-bar php browse-manual]
+      '("Browse manual" . php-browse-manual))
+    (define-key map [menu-bar php search-documentation]
+      '("Search documentation" . php-search-documentation))
+
+    ;; By default PHP mode binds C-M-h to c-mark-function, which it
+    ;; inherits from cc-mode.  But there are situations where
+    ;; c-mark-function fails to properly mark a function.  For
+    ;; example, if we use c-mark-function within a method definition
+    ;; then the region will expand beyond the method and into the
+    ;; class definition itself.
+    ;;
+    ;; Changing the default to mark-defun provides behavior that users
+    ;; are more likely to expect.
+    (define-key map (kbd "C-M-h") 'mark-defun)
+
+    ;; Many packages based on cc-mode provide the 'C-c C-w' binding
+    ;; to toggle Subword Mode.  See the page
+    ;;
+    ;;     https://www.gnu.org/software/emacs/manual/html_node/ccmode/Subword-Movement.html
+    ;;
+    ;; for more information about Submode Word.
+    (if (boundp 'subword-mode)
+        (if subword-mode
+            (subword-mode nil)
+          (subword-mode t)))
+
+    ;; We inherit c-beginning-of-defun and c-end-of-defun from CC Mode
+    ;; but we have two replacement functions specifically for PHP.  We
+    ;; remap the commands themselves and not their default
+    ;; key-bindings so that our PHP-specific versions will work even
+    ;; if the user has reconfigured their keys, e.g. if they rebind
+    ;; c-end-of-defun to something other than C-M-e.
+    (define-key map [remap c-beginning-of-defun] 'php-beginning-of-defun)
+    (define-key map [remap c-end-of-defun] 'php-end-of-defun)
+
+    (define-key map [(control c) (control f)] 'php-search-documentation)
+    (define-key map [(meta tab)] 'php-complete-function)
+    (define-key map [(control c) (control m)] 'php-browse-manual)
+    (define-key map [(control .)] 'php-show-arglist)
+    (define-key map [(control c) (control r)] 'php-send-region)
+    ;; Use the Emacs standard indentation binding. This may upset c-mode
+    ;; which does not follow this at the moment, but I see no better
+    ;; choice.
+    (define-key map [tab] 'indent-for-tab-command)
+    map)
+  "Keymap for `php-mode'")
+
+(eval-and-compile
+  ;; PHP-SYNTAX-PROPERTIZE-FUNCTION requires PHP-HEREDOC-START-RE
+  ;; available at compile time. So wrap in `eval-and-compile'.
+  (defconst php-heredoc-start-re
+    "<<<\\(?:\\w+\\|'\\w+'\\)$"
+    "Regular expression for the start of a PHP heredoc."))
+
+(defun php-heredoc-end-re (heredoc-start)
+  "Build a regular expression for the end of a heredoc started by
+the string HEREDOC-START."
+  ;; Extract just the identifier without <<< and quotes.
+  (string-match "\\w+" heredoc-start)
+  (concat "^\\(" (match-string 0 heredoc-start) "\\)\\W"))
+
+(defconst php-syntax-propertize-function
+  (syntax-propertize-rules
+   (php-heredoc-start-re (0 (ignore (php-heredoc-syntax))))))
+
+(defun php-heredoc-syntax ()
+  "Mark the boundaries of searched heredoc."
+  (goto-char (match-beginning 0))
+  (c-put-char-property (point) 'syntax-table (string-to-syntax "|"))
+  (if (re-search-forward (php-heredoc-end-re (match-string 0)) nil t)
+      (goto-char (match-end 1))
+    ;; Did not find the delimiter so go to the end of the buffer.
+    (goto-char (point-max)))
+  (c-put-char-property (1- (point)) 'syntax-table (string-to-syntax "|")))
+
+(defun php-syntax-propertize-extend-region (start end)
+  "Extend the propertize region of START falls inside a heredoc."
+  (when (re-search-backward php-heredoc-start-re nil t)
+    (let ((new-start (point)))
+      (when (and (re-search-forward
+                  (php-heredoc-end-re (match-string 0)) nil t)
+                 (> (point) start))
+        (cons new-start end)))))
+
+;;;###autoload
+(define-derived-mode php-mode c-mode "PHP"
+  "Major mode for editing PHP code.\n\n\\{php-mode-map}"
+  (c-add-language 'php-mode 'c-mode)
+
+  ;; PHP doesn't have C-style macros.
+  ;; HACK: Overwrite this syntax with rules to match <?php and others.
+  (set (make-local-variable 'c-opt-cpp-start) php-tags-key)
+  (set (make-local-variable 'c-opt-cpp-prefix) php-tags-key)
+
+  (set (make-local-variable 'c-block-stmt-1-key) php-block-stmt-1-key)
+  (set (make-local-variable 'c-block-stmt-2-key) php-block-stmt-2-key)
+
+  ;; Specify that cc-mode recognize Javadoc comment style
+  (set (make-local-variable 'c-doc-comment-style)
+    '((php-mode . javadoc)))
+
+  (set (make-local-variable 'c-class-key) php-class-key)
+
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults
+        '((php-font-lock-keywords-1
+           php-font-lock-keywords-2
+           ;; Comment-out the next line if the font-coloring is too
+           ;; extreme/ugly for you.
+           php-font-lock-keywords-3)
+          nil                ; KEYWORDS-ONLY
+          t                  ; CASE-FOLD
+          (("_" . "w"))      ; SYNTAX-ALIST
+          nil))              ; SYNTAX-BEGIN
+
+  (modify-syntax-entry ?_    "_" php-mode-syntax-table)
+  (modify-syntax-entry ?`    "\"" php-mode-syntax-table)
+  (modify-syntax-entry ?\"   "\"" php-mode-syntax-table)
+  (modify-syntax-entry ?#    "< b" php-mode-syntax-table)
+  (modify-syntax-entry ?\n   "> b" php-mode-syntax-table)
+
+  (set (make-local-variable 'syntax-propertize-via-font-lock)
+       '(("\\(\"\\)\\(\\\\.\\|[^\"\n\\]\\)*\\(\"\\)" (1 "\"") (3 "\""))
+         ("\\(\'\\)\\(\\\\.\\|[^\'\n\\]\\)*\\(\'\\)" (1 "\"") (3 "\""))))
+
+  (add-to-list (make-local-variable 'syntax-propertize-extend-region-functions)
+               'php-syntax-propertize-extend-region)
+  (set (make-local-variable 'syntax-propertize-function)
+       php-syntax-propertize-function)
+
+  (setq font-lock-maximum-decoration t
+        imenu-generic-expression php-imenu-generic-expression)
+
+  ;; PHP vars are case-sensitive
+  (setq case-fold-search t)
+
+  ;; Do not force newline at end of file.  Such newlines can cause
+  ;; trouble if the PHP file is included in another file before calls
+  ;; to header() or cookie().
+  (set (make-local-variable 'require-final-newline) nil)
+  (set (make-local-variable 'next-line-add-newlines) nil)
+
+  ;; PEAR coding standards
+  (add-hook 'php-mode-pear-hook 'php-enable-pear-coding-style
+             nil t)
+
+  ;; ;; Drupal coding standards
+  (add-hook 'php-mode-drupal-hook 'php-enable-drupal-coding-style
+             nil t)
+
+  ;; ;; WordPress coding standards
+  (add-hook 'php-mode-wordpress-hook 'php-enable-wordpress-coding-style
+             nil t)
+
+  ;; ;; Symfony2 coding standards
+  (add-hook 'php-mode-symfony2-hook 'php-enable-symfony2-coding-style
+             nil t)
+
+  (cond ((eq php-mode-coding-style 'pear)
+         (php-enable-pear-coding-style)
+         (run-hooks 'php-mode-pear-hook))
+        ((eq php-mode-coding-style 'drupal)
+         (php-enable-drupal-coding-style)
+         (run-hooks 'php-mode-drupal-hook))
+        ((eq php-mode-coding-style 'wordpress)
+         (php-enable-wordpress-coding-style)
+         (run-hooks 'php-mode-wordpress-hook))
+        ((eq php-mode-coding-style 'symfony2)
+         (php-enable-symfony2-coding-style)
+         (run-hooks 'php-mode-symfony2-hook)))
+
+  (if (or php-mode-force-pear
+          (and (stringp buffer-file-name)
+               (string-match "PEAR\\|pear"
+                             (buffer-file-name))
+               (string-match "\\.php$" (buffer-file-name))))
+      (run-hooks 'php-mode-pear-hook))
+
+  (setq indent-line-function 'php-cautious-indent-line)
+  (setq indent-region-function 'php-cautious-indent-region)
+  (add-hook 'c-special-indent-hook 'php-unindent-closure)
+  (setq c-at-vsemi-p-fn 'php-c-at-vsemi-p)
+  (setq c-vsemi-status-unknown-p 'php-c-vsemi-status-unknown-p)
+
+  (set (make-local-variable 'syntax-begin-function)
+       'c-beginning-of-syntax)
+
+  ;; We map the php-{beginning,end}-of-defun functions so that they
+  ;; replace the similar commands that we inherit from CC Mode.
+  ;; Because of our remapping we may not actually need to keep the
+  ;; following two local variables, but we keep them for now until we
+  ;; are completely sure their removal will not break any current
+  ;; behavior or backwards compatibility.
+  (set (make-local-variable 'beginning-of-defun-function)
+       'php-beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function)
+       'php-end-of-defun)
+
+  (set (make-local-variable 'open-paren-in-column-0-is-defun-start)
+       nil)
+  (set (make-local-variable 'defun-prompt-regexp)
+       "^\\s-*function\\s-+&?\\s-*\\(\\(\\sw\\|\\s_\\)+\\)\\s-*")
+  (set (make-local-variable 'add-log-current-defun-header-regexp)
+       php-beginning-of-defun-regexp))
+
+;; Define function name completion function
+(defvar php-completion-table nil
+  "Obarray of tag names defined in current tags table and functions known to PHP.")
+
+(defun php-complete-function ()
+  "Perform function completion on the text around point.
+Completes to the set of names listed in the current tags table
+and the standard php functions.
+The string to complete is chosen in the same way as the default
+for \\[find-tag] (which see)."
+  (interactive)
+  (let ((pattern (php-get-pattern))
+        beg
+        completion
+        (php-functions (php-completion-table)))
+    (if (not pattern) (message "Nothing to complete")
+        (if (not (search-backward pattern nil t))
+            (message "Can't complete here")
+          (setq beg (point))
+          (forward-char (length pattern))
+          (setq completion (try-completion pattern php-functions nil))
+          (cond ((eq completion t))
+                ((null completion)
+                 (message "Can't find completion for \"%s\"" pattern)
+                 (ding))
+                ((not (string= pattern completion))
+                 (delete-region beg (point))
+                 (insert completion))
+                (t
+                 (message "Making completion list...")
+                 (with-output-to-temp-buffer "*Completions*"
+                   (display-completion-list
+                    (all-completions pattern php-functions)))
+                 (message "Making completion list...%s" "done")))))))
+
+(defun php-completion-table ()
+  "Build variable `php-completion-table' on demand.
+The table includes the PHP functions and the tags from the
+current `tags-file-name'."
+  (or (and tags-file-name
+           (save-excursion (tags-verify-table tags-file-name))
+           php-completion-table)
+      (let ((tags-table
+             (when tags-file-name
+               (with-current-buffer (get-file-buffer tags-file-name)
+                 (etags-tags-completion-table))))
+            (php-table
+             (cond ((and (not (string= "" php-completion-file))
+                         (file-readable-p php-completion-file))
+                    (php-build-table-from-file php-completion-file))
+                   (php-manual-path
+                    (php-build-table-from-path php-manual-path))
+                   (t nil))))
+        (unless (or php-table tags-table)
+          (error
+           (concat "No TAGS file active nor are "
+                   "`php-completion-file' or `php-manual-path' set")))
+        (when tags-table
+          ;; Combine the tables.
+          (mapatoms (lambda (sym) (intern (symbol-name sym) php-table))
+                    tags-table))
+        (setq php-completion-table php-table))))
+
+(defun php-build-table-from-file (filename)
+  (let ((table (make-vector 1022 0))
+        (buf (find-file-noselect filename)))
+    (with-current-buffer buf
+      (goto-char (point-min))
+      (while (re-search-forward
+              "^\\([-a-zA-Z0-9_.]+\\)\n"
+              nil t)
+        (intern (buffer-substring (match-beginning 1) (match-end 1))
+                table)))
+    (kill-buffer buf)
+    table))
+
+(defun php-build-table-from-path (path)
+  (let ((table (make-vector 1022 0))
+        (files (directory-files
+                path
+                nil
+                "^function\\..+\\.html$")))
+    (mapc (lambda (file)
+            (string-match "\\.\\([-a-zA-Z_0-9]+\\)\\.html$" file)
+            (intern
+             (replace-regexp-in-string
+              "-" "_" (substring file (match-beginning 1) (match-end 1)) t)
+             table))
+          files)
+    table))
+
+;; Find the pattern we want to complete
+;; find-tag-default from GNU Emacs etags.el
+(defun php-get-pattern ()
+  (save-excursion
+    (while (looking-at "\\sw\\|\\s_")
+      (forward-char 1))
+    (if (or (re-search-backward "\\sw\\|\\s_"
+                                (save-excursion (beginning-of-line) (point))
+                                t)
+            (re-search-forward "\\(\\sw\\|\\s_\\)+"
+                               (save-excursion (end-of-line) (point))
+                               t))
+        (progn (goto-char (match-end 0))
+               (buffer-substring-no-properties
+                (point)
+                (progn (forward-sexp -1)
+                       (while (looking-at "\\s'")
+                         (forward-char 1))
+                       (point))))
+      nil)))
+
+(defun php-show-arglist ()
+  (interactive)
+  (let* ((tagname (php-get-pattern))
+         (buf (find-tag-noselect tagname nil nil))
+         arglist)
+    (with-current-buffer buf
+      (goto-char (point-min))
+      (when (re-search-forward
+             (format "function\\s-+%s\\s-*(\\([^{]*\\))" tagname)
+             nil t)
+        (setq arglist (buffer-substring-no-properties
+                       (match-beginning 1) (match-end 1)))))
+    (if arglist
+        (message "Arglist for %s: %s" tagname arglist)
+        (message "Unknown function: %s" tagname))))
+
+(defun php-search-local-documentation ()
+  "Search the local PHP documentation (i.e. in `php-manual-path')
+for the word at point.  The function returns t if the requested
+documentation exists, and nil otherwise."
+  (interactive)
+  (cl-flet ((php-function-file-for (name)
+                                (expand-file-name
+                                 (format "function.%s.html"
+                                         (replace-regexp-in-string "_" "-" name))
+                                 php-manual-path)))
+    (let ((doc-file (php-function-file-for (current-word))))
+      (and (file-exists-p doc-file)
+           (browse-url doc-file)
+           t))))
+
+;; Define function documentation function
+(defun php-search-documentation ()
+  "Search PHP documentation for the word at point.  If
+`php-manual-path' has a non-empty string value then the command
+will first try searching the local documentation.  If the
+requested documentation does not exist it will fallback to
+searching the PHP website."
+  (interactive)
+  (cl-flet ((php-search-web-documentation ()
+                                       (browse-url (concat php-search-url (current-word)))))
+    (if (and (stringp php-manual-path)
+             (not (string= php-manual-path "")))
+        (or (php-search-local-documentation)
+            (php-search-web-documentation))
+      (php-search-web-documentation))))
+
+;; Define function for browsing manual
+(defun php-browse-manual ()
+  "Bring up manual for PHP."
+  (interactive)
+  (browse-url php-manual-url))
+
+
+(defconst php-constants
+  (regexp-opt
+   (append
+    php-extra-constants
+    (when (boundp 'web-mode-extra-php-constants) web-mode-extra-php-constants)
+    '( ;; core constants
+      "__LINE__" "__FILE__" "__DIR__"
+      "__FUNCTION__" "__CLASS__" "__TRAIT__" "__METHOD__"
+      "__NAMESPACE__"
+      "__COMPILER_HALT_OFFSET__"
+      "PHP_OS" "PHP_VERSION"
+      "PHP_MINOR_VERSION" "PHP_MAJOR_VERSION" "PHP_RELEASE_VERSION"
+      "PHP_VERSION_ID" "PHP_EXTRA_VERSION"
+      "TRUE" "FALSE" "NULL"
+      "E_ERROR" "E_NOTICE" "E_PARSE" "E_WARNING" "E_ALL" "E_STRICT"
+      "E_USER_ERROR" "E_USER_WARNING" "E_USER_NOTICE"
+      "E_CORE_ERROR" "E_CORE_WARNING"
+      "E_COMPILE_ERROR" "E_COMPILE_WARNING"
+      "E_DEPRECATED" "E_USER_DEPRECATED"
+      "DEFAULT_INCLUDE_PATH" "PEAR_INSTALL_DIR" "PEAR_EXTENSION_DIR"
+      "PHP_BINDIR" "PHP_LIBDIR" "PHP_DATADIR" "PHP_SYSCONFDIR"
+      "PHP_LOCALSTATEDIR" "PHP_CONFIG_FILE_PATH"
+      "PHP_EOL"
+      "PHP_ZTS"
+      "PHP_DEBUG"
+      "PHP_MAXPATHLEN"
+      "PHP_SAPI"
+      "PHP_INT_MAX" "PHP_INT_SIZE"
+      "PHP_EXTENSION_DIR"
+      "PHP_PREFIX"
+      "PHP_MANDIR"
+      "PHP_CONFIG_FILE_SCAN_DIR"
+
+      "PHP_WINDOWS_VERSION_MAJOR"
+      "PHP_WINDOWS_VERSION_MINOR"
+      "PHP_WINDOWS_VERSION_BUILD"
+      "PHP_WINDOWS_VERSION_PLATFORM"
+      "PHP_WINDOWS_VERSION_SP_MAJOR"
+      "PHP_WINDOWS_VERSION_SP_MINOR"
+      "PHP_WINDOWS_VERSION_SUITEMASK"
+      "PHP_WINDOWS_VERSION_PRODUCTTYPE"
+      "PHP_WINDOWS_NT_DOMAIN_CONTROLLER"
+      "PHP_WINDOWS_NT_SERVER"
+      "PHP_WINDOWS_NT_WORKSTATION"
+
+      ;; CLI SAPI
+      "STDIN"
+      "STDOUT"
+      "STDERR"
+
+      ;; date and time constants
+      "DATE_ATOM" "DATE_COOKIE" "DATE_ISO8601"
+      "DATE_RFC822" "DATE_RFC850" "DATE_RFC1036" "DATE_RFC1123"
+      "DATE_RFC2822" "DATE_RFC3339"
+      "DATE_RSS" "DATE_W3C"
+
+      ;; upload error message constants
+      "UPLOAD_ERR_CANT_WRITE" "UPLOAD_ERR_EXTENSION"
+      "UPLOAD_ERR_FORM_SIZE" "UPLOAD_ERR_INI_SIZE"
+      "UPLOAD_ERR_NO_FILE" "UPLOAD_ERR_NO_TMP_DIR"
+      "UPLOAD_ERR_OK" "UPLOAD_ERR_PARTIAL"
+
+      ;; from ext/standard:
+      "EXTR_OVERWRITE"
+      "EXTR_PREFIX_SAME"
+      "EXTR_PREFIX_INVALID"
+      "EXTR_IF_EXISTS"
+      "SORT_DESC"
+      "SORT_NUMERIC"
+      "CASE_LOWER"
+      "COUNT_NORMAL"
+      "ASSERT_ACTIVE"
+      "ASSERT_BAIL"
+      "ASSERT_QUIET_EVAL"
+      "CONNECTION_NORMAL"
+      "INI_USER"
+      "INI_SYSTEM"
+      "M_E"
+      "M_LOG10E"
+      "M_LN10"
+      "M_PI_2"
+      "M_1_PI"
+      "M_2_SQRTPI"
+      "M_SQRT1_2"
+      "CRYPT_STD_DES"
+      "CRYPT_MD5"
+      "DIRECTORY_SEPARATOR"
+      "SEEK_CUR"
+      "LOCK_SH"
+      "LOCK_UN"
+      "HTML_SPECIALCHARS"
+      "ENT_COMPAT"
+      "ENT_QUOTES"
+      "ENT_NOQUOTES"
+      "ENT_IGNORE"
+      "ENT_SUBSTITUTE"
+      "ENT_DISALLOWED"
+      "ENT_HTML401"
+      "ENT_XML1"
+      "ENT_XHTML"
+      "ENT_HTML5"
+      "INFO_CREDITS"
+      "INFO_MODULES"
+      "INFO_VARIABLES"
+      "INFO_ALL"
+      "CREDITS_GENERAL"
+      "CREDITS_MODULES"
+      "CREDITS_FULLPAGE"
+      "CREDITS_ALL"
+      "STR_PAD_RIGHT"
+      "PATHINFO_DIRNAME"
+      "PATHINFO_EXTENSION"
+      "CHAR_MAX"
+      "LC_NUMERIC"
+      "LC_COLLATE"
+      "LC_ALL"
+      "ABDAY_1"
+      "ABDAY_3"
+      "ABDAY_5"
+      "ABDAY_7"
+      "DAY_2"
+      "DAY_4"
+      "DAY_6"
+      "ABMON_1"
+      "ABMON_3"
+      "ABMON_5"
+      "ABMON_7"
+      "ABMON_9"
+      "ABMON_11"
+      "MON_1"
+      "MON_3"
+      "MON_5"
+      "MON_7"
+      "MON_9"
+      "MON_11"
+      "AM_STR"
+      "D_T_FMT"
+      "T_FMT"
+      "ERA"
+      "ERA_D_T_FMT"
+      "ERA_T_FMT"
+      "INT_CURR_SYMBOL"
+      "CRNCYSTR"
+      "MON_THOUSANDS_SEP"
+      "POSITIVE_SIGN"
+      "INT_FRAC_DIGITS"
+      "P_CS_PRECEDES"
+      "N_CS_PRECEDES"
+      "P_SIGN_POSN"
+      "DECIMAL_POINT"
+      "THOUSANDS_SEP"
+      "GROUPING"
+      "NOEXPR"
+      "NOSTR"
+      "LOG_EMERG"
+      "LOG_CRIT"
+      "LOG_WARNING"
+      "LOG_INFO"
+      "LOG_KERN"
+      "LOG_MAIL"
+      "LOG_AUTH"
+      "LOG_LPR"
+      "LOG_UUCP"
+      "LOG_AUTHPRIV"
+      "LOG_LOCAL1"
+      "LOG_LOCAL3"
+      "LOG_LOCAL5"
+      "LOG_LOCAL7"
+      "LOG_CONS"
+      "LOG_NDELAY"
+      "LOG_PERROR"
+
+      ;; Filter constants
+      "INPUT_POST"
+      "INPUT_GET"
+      "INPUT_COOKIE"
+      "INPUT_ENV"
+      "INPUT_SERVER"
+      "INPUT_SESSION"
+      "INPUT_REQUEST"
+      "FILTER_FLAG_NONE"
+      "FILTER_REQUIRE_SCALAR"
+      "FILTER_REQUIRE_ARRAY"
+      "FILTER_FORCE_ARRAY"
+      "FILTER_NULL_ON_FAILURE"
+      "FILTER_VALIDATE_INT"
+      "FILTER_VALIDATE_BOOLEAN"
+      "FILTER_VALIDATE_FLOAT"
+      "FILTER_VALIDATE_REGEXP"
+      "FILTER_VALIDATE_URL"
+      "FILTER_VALIDATE_EMAIL"
+      "FILTER_VALIDATE_IP"
+      "FILTER_DEFAULT"
+      "FILTER_UNSAFE_RAW"
+      "FILTER_SANITIZE_STRING"
+      "FILTER_SANITIZE_STRIPPED"
+      "FILTER_SANITIZE_ENCODED"
+      "FILTER_SANITIZE_SPECIAL_CHARS"
+      "FILTER_SANITIZE_FULL_SPECIAL_CHARS"
+      "FILTER_SANITIZE_EMAIL"
+      "FILTER_SANITIZE_URL"
+      "FILTER_SANITIZE_NUMBER_INT"
+      "FILTER_SANITIZE_NUMBER_FLOAT"
+      "FILTER_SANITIZE_MAGIC_QUOTES"
+      "FILTER_CALLBACK"
+      "FILTER_FLAG_ALLOW_OCTAL"
+      "FILTER_FLAG_ALLOW_HEX"
+      "FILTER_FLAG_STRIP_LOW"
+      "FILTER_FLAG_STRIP_HIGH"
+      "FILTER_FLAG_ENCODE_LOW"
+      "FILTER_FLAG_ENCODE_HIGH"
+      "FILTER_FLAG_ENCODE_AMP"
+      "FILTER_FLAG_NO_ENCODE_QUOTES"
+      "FILTER_FLAG_EMPTY_STRING_NULL"
+      "FILTER_FLAG_ALLOW_FRACTION"
+      "FILTER_FLAG_ALLOW_THOUSAND"
+      "FILTER_FLAG_ALLOW_SCIENTIFIC"
+      "FILTER_FLAG_PATH_REQUIRED"
+      "FILTER_FLAG_QUERY_REQUIRED"
+      "FILTER_FLAG_IPV4"
+      "FILTER_FLAG_IPV6"
+      "FILTER_FLAG_NO_RES_RANGE"
+      "FILTER_FLAG_NO_PRIV_RANGE"
+
+      ;; Password constants
+      "PASSWORD_DEFAULT"
+      "PASSWORD_BCRYPT"
+
+      ;; PREG constants
+      "PREG_PATTERN_ORDER"
+      "PREG_SET_ORDER"
+      "PREG_OFFSET_CAPTURE"
+      "PREG_SPLIT_NO_EMPTY"
+      "PREG_SPLIT_DELIM_CAPTURE"
+      "PREG_SPLIT_OFFSET_CAPTURE"
+      "PREG_NO_ERROR"
+      "PREG_INTERNAL_ERROR"
+      "PREG_BACKTRACK_LIMIT_ERROR"
+      "PREG_RECURSION_LIMIT_ERROR"
+      "PREG_BAD_UTF8_ERROR"
+      "PREG_BAD_UTF8_OFFSET_ERROR"
+      "PCRE_VERSION"
+
+      ;; cURL constants
+      "CURLOPT_AUTOREFERER"
+      "CURLOPT_COOKIESESSION"
+      "CURLOPT_DNS_USE_GLOBAL_CACHE"
+      "CURLOPT_DNS_CACHE_TIMEOUT"
+      "CURLOPT_FTP_SSL"
+      "CURLFTPSSL_TRY"
+      "CURLFTPSSL_ALL"
+      "CURLFTPSSL_CONTROL"
+      "CURLFTPSSL_NONE"
+      "CURLOPT_PRIVATE"
+      "CURLOPT_FTPSSLAUTH"
+      "CURLOPT_PORT"
+      "CURLOPT_FILE"
+      "CURLOPT_INFILE"
+      "CURLOPT_INFILESIZE"
+      "CURLOPT_URL"
+      "CURLOPT_PROXY"
+      "CURLOPT_VERBOSE"
+      "CURLOPT_HEADER"
+      "CURLOPT_HTTPHEADER"
+      "CURLOPT_NOPROGRESS"
+      "CURLOPT_NOBODY"
+      "CURLOPT_FAILONERROR"
+      "CURLOPT_UPLOAD"
+      "CURLOPT_POST"
+      "CURLOPT_FTPLISTONLY"
+      "CURLOPT_FTPAPPEND"
+      "CURLOPT_FTP_CREATE_MISSING_DIRS"
+      "CURLOPT_NETRC"
+      "CURLOPT_FOLLOWLOCATION"
+      "CURLOPT_FTPASCII"
+      "CURLOPT_PUT"
+      "CURLOPT_MUTE"
+      "CURLOPT_USERPWD"
+      "CURLOPT_PROXYUSERPWD"
+      "CURLOPT_RANGE"
+      "CURLOPT_TIMEOUT"
+      "CURLOPT_TIMEOUT_MS"
+      "CURLOPT_TCP_NODELAY"
+      "CURLOPT_POSTFIELDS"
+      "CURLOPT_PROGRESSFUNCTION"
+      "CURLOPT_REFERER"
+      "CURLOPT_USERAGENT"
+      "CURLOPT_FTPPORT"
+      "CURLOPT_FTP_USE_EPSV"
+      "CURLOPT_LOW_SPEED_LIMIT"
+      "CURLOPT_LOW_SPEED_TIME"
+      "CURLOPT_RESUME_FROM"
+      "CURLOPT_COOKIE"
+      "CURLOPT_SSLCERT"
+      "CURLOPT_SSLCERTPASSWD"
+      "CURLOPT_WRITEHEADER"
+      "CURLOPT_SSL_VERIFYHOST"
+      "CURLOPT_COOKIEFILE"
+      "CURLOPT_SSLVERSION"
+      "CURLOPT_TIMECONDITION"
+      "CURLOPT_TIMEVALUE"
+      "CURLOPT_CUSTOMREQUEST"
+      "CURLOPT_STDERR"
+      "CURLOPT_TRANSFERTEXT"
+      "CURLOPT_RETURNTRANSFER"
+      "CURLOPT_QUOTE"
+      "CURLOPT_POSTQUOTE"
+      "CURLOPT_INTERFACE"
+      "CURLOPT_KRB4LEVEL"
+      "CURLOPT_HTTPPROXYTUNNEL"
+      "CURLOPT_FILETIME"
+      "CURLOPT_WRITEFUNCTION"
+      "CURLOPT_READFUNCTION"
+      "CURLOPT_PASSWDFUNCTION"
+      "CURLOPT_HEADERFUNCTION"
+      "CURLOPT_MAXREDIRS"
+      "CURLOPT_MAXCONNECTS"
+      "CURLOPT_CLOSEPOLICY"
+      "CURLOPT_FRESH_CONNECT"
+      "CURLOPT_FORBID_REUSE"
+      "CURLOPT_RANDOM_FILE"
+      "CURLOPT_EGDSOCKET"
+      "CURLOPT_CONNECTTIMEOUT"
+      "CURLOPT_CONNECTTIMEOUT_MS"
+      "CURLOPT_SSL_VERIFYPEER"
+      "CURLOPT_CAINFO"
+      "CURLOPT_CAPATH"
+      "CURLOPT_COOKIEJAR"
+      "CURLOPT_SSL_CIPHER_LIST"
+      "CURLOPT_BINARYTRANSFER"
+      "CURLOPT_NOSIGNAL"
+      "CURLOPT_PROXYTYPE"
+      "CURLOPT_BUFFERSIZE"
+      "CURLOPT_HTTPGET"
+      "CURLOPT_HTTP_VERSION"
+      "CURLOPT_SSLKEY"
+      "CURLOPT_SSLKEYTYPE"
+      "CURLOPT_SSLKEYPASSWD"
+      "CURLOPT_SSLENGINE"
+      "CURLOPT_SSLENGINE_DEFAULT"
+      "CURLOPT_SSLCERTTYPE"
+      "CURLOPT_CRLF"
+      "CURLOPT_ENCODING"
+      "CURLOPT_PROXYPORT"
+      "CURLOPT_UNRESTRICTED_AUTH"
+      "CURLOPT_FTP_USE_EPRT"
+      "CURLOPT_HTTP200ALIASES"
+      "CURLOPT_HTTPAUTH"
+      "CURLAUTH_BASIC"
+      "CURLAUTH_DIGEST"
+      "CURLAUTH_GSSNEGOTIATE"
+      "CURLAUTH_NTLM"
+      "CURLAUTH_ANY"
+      "CURLAUTH_ANYSAFE"
+      "CURLOPT_PROXYAUTH"
+      "CURLOPT_MAX_RECV_SPEED_LARGE"
+      "CURLOPT_MAX_SEND_SPEED_LARGE"
+      "CURLCLOSEPOLICY_LEAST_RECENTLY_USED"
+      "CURLCLOSEPOLICY_LEAST_TRAFFIC"
+      "CURLCLOSEPOLICY_SLOWEST"
+      "CURLCLOSEPOLICY_CALLBACK"
+      "CURLCLOSEPOLICY_OLDEST"
+      "CURLINFO_PRIVATE"
+      "CURLINFO_EFFECTIVE_URL"
+      "CURLINFO_HTTP_CODE"
+      "CURLINFO_HEADER_OUT"
+      "CURLINFO_HEADER_SIZE"
+      "CURLINFO_REQUEST_SIZE"
+      "CURLINFO_TOTAL_TIME"
+      "CURLINFO_NAMELOOKUP_TIME"
+      "CURLINFO_CONNECT_TIME"
+      "CURLINFO_PRETRANSFER_TIME"
+      "CURLINFO_SIZE_UPLOAD"
+      "CURLINFO_SIZE_DOWNLOAD"
+      "CURLINFO_SPEED_DOWNLOAD"
+      "CURLINFO_SPEED_UPLOAD"
+      "CURLINFO_FILETIME"
+      "CURLINFO_SSL_VERIFYRESULT"
+      "CURLINFO_CONTENT_LENGTH_DOWNLOAD"
+      "CURLINFO_CONTENT_LENGTH_UPLOAD"
+      "CURLINFO_STARTTRANSFER_TIME"
+      "CURLINFO_CONTENT_TYPE"
+      "CURLINFO_REDIRECT_TIME"
+      "CURLINFO_REDIRECT_COUNT"
+      "CURL_TIMECOND_IFMODSINCE"
+      "CURL_TIMECOND_IFUNMODSINCE"
+      "CURL_TIMECOND_LASTMOD"
+      "CURL_VERSION_IPV6"
+      "CURL_VERSION_KERBEROS4"
+      "CURL_VERSION_SSL"
+      "CURL_VERSION_LIBZ"
+      "CURLVERSION_NOW"
+      "CURLE_OK"
+      "CURLE_UNSUPPORTED_PROTOCOL"
+      "CURLE_FAILED_INIT"
+      "CURLE_URL_MALFORMAT"
+      "CURLE_URL_MALFORMAT_USER"
+      "CURLE_COULDNT_RESOLVE_PROXY"
+      "CURLE_COULDNT_RESOLVE_HOST"
+      "CURLE_COULDNT_CONNECT"
+      "CURLE_FTP_WEIRD_SERVER_REPLY"
+      "CURLE_FTP_ACCESS_DENIED"
+      "CURLE_FTP_USER_PASSWORD_INCORRECT"
+      "CURLE_FTP_WEIRD_PASS_REPLY"
+      "CURLE_FTP_WEIRD_USER_REPLY"
+      "CURLE_FTP_WEIRD_PASV_REPLY"
+      "CURLE_FTP_WEIRD_227_FORMAT"
+      "CURLE_FTP_CANT_GET_HOST"
+      "CURLE_FTP_CANT_RECONNECT"
+      "CURLE_FTP_COULDNT_SET_BINARY"
+      "CURLE_PARTIAL_FILE"
+      "CURLE_FTP_COULDNT_RETR_FILE"
+      "CURLE_FTP_WRITE_ERROR"
+      "CURLE_FTP_QUOTE_ERROR"
+      "CURLE_HTTP_NOT_FOUND"
+      "CURLE_WRITE_ERROR"
+      "CURLE_MALFORMAT_USER"
+      "CURLE_FTP_COULDNT_STOR_FILE"
+      "CURLE_READ_ERROR"
+      "CURLE_OUT_OF_MEMORY"
+      "CURLE_OPERATION_TIMEOUTED"
+      "CURLE_FTP_COULDNT_SET_ASCII"
+      "CURLE_FTP_PORT_FAILED"
+      "CURLE_FTP_COULDNT_USE_REST"
+      "CURLE_FTP_COULDNT_GET_SIZE"
+      "CURLE_HTTP_RANGE_ERROR"
+      "CURLE_HTTP_POST_ERROR"
+      "CURLE_SSL_CONNECT_ERROR"
+      "CURLE_FTP_BAD_DOWNLOAD_RESUME"
+      "CURLE_FILE_COULDNT_READ_FILE"
+      "CURLE_LDAP_CANNOT_BIND"
+      "CURLE_LDAP_SEARCH_FAILED"
+      "CURLE_LIBRARY_NOT_FOUND"
+      "CURLE_FUNCTION_NOT_FOUND"
+      "CURLE_ABORTED_BY_CALLBACK"
+      "CURLE_BAD_FUNCTION_ARGUMENT"
+      "CURLE_BAD_CALLING_ORDER"
+      "CURLE_HTTP_PORT_FAILED"
+      "CURLE_BAD_PASSWORD_ENTERED"
+      "CURLE_TOO_MANY_REDIRECTS"
+      "CURLE_UNKNOWN_TELNET_OPTION"
+      "CURLE_TELNET_OPTION_SYNTAX"
+      "CURLE_OBSOLETE"
+      "CURLE_SSL_PEER_CERTIFICATE"
+      "CURLE_GOT_NOTHING"
+      "CURLE_SSL_ENGINE_NOTFOUND"
+      "CURLE_SSL_ENGINE_SETFAILED"
+      "CURLE_SEND_ERROR"
+      "CURLE_RECV_ERROR"
+      "CURLE_SHARE_IN_USE"
+      "CURLE_SSL_CERTPROBLEM"
+      "CURLE_SSL_CIPHER"
+      "CURLE_SSL_CACERT"
+      "CURLE_BAD_CONTENT_ENCODING"
+      "CURLE_LDAP_INVALID_URL"
+      "CURLE_FILESIZE_EXCEEDED"
+      "CURLE_FTP_SSL_FAILED"
+      "CURLFTPAUTH_DEFAULT"
+      "CURLFTPAUTH_SSL"
+      "CURLFTPAUTH_TLS"
+      "CURLPROXY_HTTP"
+      "CURLPROXY_SOCKS5"
+      "CURL_NETRC_OPTIONAL"
+      "CURL_NETRC_IGNORED"
+      "CURL_NETRC_REQUIRED"
+      "CURL_HTTP_VERSION_NONE"
+      "CURL_HTTP_VERSION_1_0"
+      "CURL_HTTP_VERSION_1_1"
+      "CURLM_CALL_MULTI_PERFORM"
+      "CURLM_OK"
+      "CURLM_BAD_HANDLE"
+      "CURLM_BAD_EASY_HANDLE"
+      "CURLM_OUT_OF_MEMORY"
+      "CURLM_INTERNAL_ERROR"
+      "CURLMSG_DONE"
+      "CURLOPT_KEYPASSWD"
+      "CURLOPT_SSH_AUTH_TYPES"
+      "CURLOPT_SSH_HOST_PUBLIC_KEY_MD5"
+      "CURLOPT_SSH_PRIVATE_KEYFILE"
+      "CURLOPT_SSH_PUBLIC_KEYFILE"
+      "CURLSSH_AUTH_ANY"
+      "CURLSSH_AUTH_DEFAULT"
+      "CURLSSH_AUTH_HOST"
+      "CURLSSH_AUTH_KEYBOARD"
+      "CURLSSH_AUTH_NONE"
+      "CURLSSH_AUTH_PASSWORD"
+      "CURLSSH_AUTH_PUBLICKEY"
+
+      ;; IMAP constants
+      "NIL"
+      "OP_DEBUG"
+      "OP_READONLY"
+      "OP_ANONYMOUS"
+      "OP_SHORTCACHE"
+      "OP_SILENT"
+      "OP_PROTOTYPE"
+      "OP_HALFOPEN"
+      "OP_EXPUNGE"
+      "OP_SECURE"
+      "CL_EXPUNGE"
+      "FT_UID"
+      "FT_PEEK"
+      "FT_NOT"
+      "FT_INTERNAL"
+      "FT_PREFETCHTEXT"
+      "ST_UID"
+      "ST_SILENT"
+      "ST_SET"
+      "CP_UID"
+      "CP_MOVE"
+      "SE_UID"
+      "SE_FREE"
+      "SE_NOPREFETCH"
+      "SO_FREE"
+      "SO_NOSERVER"
+      "SA_MESSAGES"
+      "SA_RECENT"
+      "SA_UNSEEN"
+      "SA_UIDNEXT"
+      "SA_UIDVALIDITY"
+      "SA_ALL"
+      "LATT_NOINFERIORS"
+      "LATT_NOSELECT"
+      "LATT_MARKED"
+      "LATT_UNMARKED"
+      "SORTDATE"
+      "SORTARRIVAL"
+      "SORTFROM"
+      "SORTSUBJECT"
+      "SORTTO"
+      "SORTCC"
+      "SORTSIZE"
+      "TYPETEXT"
+      "TYPEMULTIPART"
+      "TYPEMESSAGE"
+      "TYPEAPPLCATION"
+      "TYPEAUDIO"
+      "TYPEIMAGE"
+      "TYPEVIDEO"
+      "TYPEOTHER"
+      "ENC7BIT"
+      "ENC8BIT"
+      "ENCBINARY"
+      "ENCBASE64"
+      "ENCQUOTEDPRINTABLE"
+      "ENCOTHER"
+      "IMAP_OPENTIMEOUT"
+      "IMAP_READTIMEOUT"
+      "IMAP_WRITETIMEOUT"
+      "IMAP_CLOSETIMEOUT"
+      "LATT_REFERRAL"
+      "LATT_HASCHILDREN"
+      "LATT_HASNOCHILDREN"
+      "TYPEMODEL"
+      "IMAP_GC_ELT"
+      "IMAP_GC_ENV"
+      "IMAP_GC_TEXTS")))
+  "PHP constants.")
+
+(defconst php-keywords
+  (eval-when-compile
+    (regexp-opt
+     (append
+      (when (boundp 'web-mode-extra-php-keywords) web-mode-extra-php-keywords)
+      ;; "class", "new" and "extends" get special treatment
+      ;; "case" gets special treatment elsewhere
+      '("abstract"
+        "and"
+        "array"
+        "as"
+        "break"
+        "catch all"
+        "catch"
+        "clone"
+        "const"
+        "continue"
+        "declare"
+        "default"
+        "die"
+        "do"
+        "echo"
+        "else"
+        "elseif"
+        "empty"
+        "encoding"
+        "enddeclare"
+        "endfor"
+        "endforeach"
+        "endif"
+        "endswitch"
+        "endwhile"
+        "eval"
+        "exit"
+        "extends"
+        "final"
+        "finally"
+        "for"
+        "foreach"
+        "function"
+        "global"
+        "if"
+        "include"
+        "include_once"
+        "instanceof"
+        "insteadof"
+        "isset"
+        "list"
+        "or"
+        "private"
+        "protected"
+        "public"
+        "require"
+        "require_once"
+        "return"
+        "static"
+        "switch"
+        "throw"
+        "ticks"
+        "try"
+        "unset"
+        "use"
+        "var"
+        "while"
+        "xor"
+        "yield"))))
+  "PHP keywords.")
+
+(defconst php-types
+  (eval-when-compile
+    (regexp-opt '("array" "bool" "boolean" "callable" "char" "double" "float"
+                  "int" "integer" "long" "mixed" "object" "real"
+                  "string")))
+  "PHP types.")
+
+(defconst php-superglobals
+  (eval-when-compile
+    (regexp-opt '("_GET" "_POST" "_COOKIE" "_SESSION" "_ENV" "GLOBALS"
+                  "_SERVER" "_FILES" "_REQUEST")))
+  "PHP superglobal variables.")
+
+;; Set up font locking
+(defconst php-font-lock-keywords-1
+  (append
+   (list
+
+    ;; Fontify constants
+    (cons
+     (concat "[^_$]?\\<\\(" php-constants "\\)\\>[^_]?")
+     '(1 font-lock-constant-face))
+
+    ;; Fontify keywords
+    (cons
+     (concat "[^_$]?\\<\\(" php-keywords "\\)\\>[^_]?")
+     '(1 font-lock-keyword-face))
+
+    ;; Fontify keywords and targets, and case default tags.
+    (list "\\<\\(break\\|case\\|continue\\)\\>\\s-+\\(-?\\sw+\\)?"
+          '(1 font-lock-keyword-face) '(2 font-lock-constant-face keep t))
+    ;; This must come after the one for keywords and targets.
+    '(":" ("^\\s-+\\(\\sw+\\)\\s-+\\s-+$"
+           (beginning-of-line) (end-of-line)
+           (1 font-lock-constant-face)))
+
+    ;; treat 'print' as keyword only when not used like a function name
+    '("\\<print\\s-*(" . php-function-call-face)
+    '("\\<print\\>" . font-lock-keyword-face)
+
+    ;; Fontify PHP tag
+    (cons php-tags-key font-lock-preprocessor-face)
+
+    )
+
+   (if php-template-compatibility
+       (list
+        ;; Fontify ASP-style tag
+        '("<\\%\\(=\\)?" . font-lock-preprocessor-face)
+        '("\\%>" . font-lock-preprocessor-face))
+     ())
+
+   )
+  "Subdued level highlighting for PHP mode.")
+
+(defconst php-font-lock-keywords-2
+  (append
+   php-font-lock-keywords-1
+   (list
+
+    ;; namespace, class, interface, and trait declarations
+    '("\\<\\(namespace\\|class\\|interface\\|trait\\)\\s-+\\(\\(?:\\sw\\|\\\\\\)+\\)?"
+      (1 font-lock-keyword-face)
+      (2 font-lock-type-face nil t))
+
+    ;; handle several words specially, to include following word,
+    ;; thereby excluding it from unknown-symbol checks later
+    ;; FIX to handle implementing multiple
+    ;; currently breaks on "class Foo implements Bar, Baz"
+    '("\\<\\(new\\|extends\\|implements\\)\\s-+\\$?\\(\\(:?\\sw\\|\\\\\\)+\\)"
+      (1 font-lock-keyword-face)
+      (2 font-lock-type-face nil t))
+
+    ;; instanceof operator
+    '("\\<instanceof\\s-+\\([^$]\\(:?\\sw\\|\\\\\\)+\\)"
+      (1 font-lock-type-face nil t))
+
+    ;; namespace imports
+    '("\\<use\\s-+\\(\\(?:\\sw\\|\\(?:,\\s-*\\)\\|\\\\\\)+\\)"
+      (1 font-lock-type-face))
+
+    ;; namespace imports with aliases
+    '("\\<use\\s-+\\(\\(?:\\sw\\|\\\\\\)+\\)\\s-+as\\s-+\\(\\(?:\\sw\\|\\\\\\)+\\)"
+      (1 font-lock-type-face)
+      (2 font-lock-type-face))
+
+    ;; constants
+    '("\\<const\\s-+\\(\\sw+\\)"
+      (1 font-lock-type-face))
+
+    ;; function declaration
+    '("\\<function\\s-+&?\\(\\sw+\\)\\s-*("
+      (1 font-lock-function-name-face nil t))
+
+    ;; self, parent, and static in class contexts
+    '("\\<\\(self\\)\\(?:::\\)" (1 font-lock-constant-face nil nil))
+    '("\\<\\(parent\\)\\(?:::\\|\\s-*(\\)" (1 font-lock-constant-face nil nil))
+    '("\\<\\(static\\)\\(?:::\\)" (1 font-lock-constant-face t nil))
+    ))
+  "Medium level highlighting for PHP mode.")
+
+(defconst php-font-lock-keywords-3
+  (append
+   php-font-lock-keywords-2
+   (if php-template-compatibility
+       (list
+        '("</?[a-z!:]+" . font-lock-constant-face)
+        ;; HTML >
+        '("<[^>]*\\(>\\)" (1 font-lock-constant-face))
+        ;; HTML tags
+        '("\\(<[a-z]+\\)[[:space:]]+\\([a-z:]+=\\)[^>]*?"
+          (1 font-lock-constant-face)
+          (2 font-lock-constant-face))
+        '("\"[[:space:]]+\\([a-z:]+=\\)" (1 font-lock-constant-face))
+        )
+     ())
+   (list
+    ;; warn about $word.word -- it could be a valid concatenation,
+    ;; but without any spaces we'll assume $word->word was meant.
+    '("\\$\\sw+\\(\\.\\)\\sw"
+      1 font-lock-warning-face)
+
+    ;; Warn about ==> instead of =>
+    '("==+>" . font-lock-warning-face)
+
+    ;; exclude casts from bare-word treatment (may contain spaces)
+    `(,(concat "(\\s-*\\(" php-types "\\)\\s-*)")
+      1 font-lock-type-face)
+
+    ;; PHP5: function declarations may contain classes as parameters type
+    `("[(,]\\(?:\\s-\\|\n\\)*\\(\\(?:\\sw\\|\\\\\\)+\\)\\s-+&?\\$\\sw+\\>"
+      1 font-lock-type-face)
+
+    ;; Function calls qualified by namespaces
+    '("\\(\\\\?\\(?:\\sw+\\\\\\)+\\)\\sw+("
+      (1 font-lock-type-face))
+
+    ;; Fontify variables and function calls
+    '("\\$\\(this\\|that\\)\\W" (1 font-lock-constant-face nil nil))
+
+    ;; $_GET & co
+    `(,(concat "\\$\\(" php-superglobals "\\)\\W")
+      (1 font-lock-constant-face nil nil))
+
+    ;; $variable
+    '("\\$\\(\\sw+\\)" (1 font-lock-variable-name-face))
+
+    ;; ->function_call
+    '("->\\(\\sw+\\)\\s-*(" (1 php-function-call-face keep t))
+
+    ;; ->variable
+    '("->\\(\\sw+\\)" (1 font-lock-variable-name-face keep t))
+
+    ;; class::member
+    '("\\(\\(\\sw\\|\\\\\\)+\\)::\\sw+\\s-*(?" . (1 font-lock-type-face))
+
+    ;; class::constant
+    '("::\\(\\(?:\\sw\\|\\s_\\)+\\>\\)[^(]" . (1 font-lock-constant-face))
+
+    ;; using a trait in a class
+    '("\\<use\\s-+\\(\\sw+\\)\\s-*;" . (1 font-lock-type-face))
+
+    ;; word(
+    '("\\<\\(\\sw+\\s-*\\)(" . (1 php-function-call-face))
+
+    ;; word[
+    '("\\<\\(\\sw+\\s-*\\)\\[" . (1 php-default-face))
+
+    ;; number (also matches word)
+    '("\\<[0-9]+" . php-default-face)
+
+    ;; Warn on any words not already fontified
+    '("\\<\\sw+\\>" . font-lock-warning-face)))
+
+  "Gauchy level highlighting for PHP mode.")
+
+
+
+;;; Provide support for Flymake so that users can see warnings and
+;;; errors in real-time as they write code.
+
+(defun flymake-php-init ()
+  (let* ((temp-file (flymake-init-create-temp-buffer-copy
+                     'flymake-create-temp-inplace))
+         (local-file (file-relative-name
+                      temp-file
+                      (file-name-directory buffer-file-name))))
+    (list php-executable (list "-f" local-file "-l"))))
+
+(add-to-list 'flymake-allowed-file-name-masks
+             '("\\.php[345s]?$"
+               flymake-php-init
+               flymake-simple-cleanup
+               flymake-get-real-file-name))
+
+(add-to-list 'flymake-err-line-patterns
+             '("\\(Parse\\|Fatal\\) error: \\(.*?\\) in \\(.*?\\) on line \\([0-9]+\\)" 3 4 nil 2))
+
+
+(defun php-send-region (start end)
+  "Send the region between `start' and `end' to PHP for execution.
+The output will appear in the buffer *PHP*."
+  (interactive "r")
+  (let ((php-buffer (get-buffer-create "*PHP*"))
+        (code (buffer-substring start end)))
+    ;; Calling 'php -r' will fail if we send it code that starts with
+    ;; '<?php', which is likely.  So we run the code through this
+    ;; function to check for that prefix and remove it.
+    (cl-flet ((clean-php-code (code)
+                           (if (string-prefix-p "<?php" code t)
+                               (substring code 5)
+                             code)))
+      (call-process "php" nil php-buffer nil "-r" (clean-php-code code)))))
+
+
+(defface php-annotations-annotation-face '((t . (:inherit 'font-lock-constant-face)))
+  "Face used to highlight annotations.")
+
+(defconst php-annotations-re "\\(\\s-\\|{\\)\\(@[[:alpha:]]+\\)")
+
+(defmacro php-annotations-inside-comment-p (pos)
+  "Return non-nil if POS is inside a comment."
+  `(or (eq (get-char-property ,pos 'face) 'font-lock-comment-face)
+       (eq (get-char-property ,pos 'face) 'font-lock-comment-delimiter-face)))
+
+(defun php-annotations-font-lock-find-annotation (limit)
+  (let ((match
+         (catch 'match
+           (save-match-data
+             (while (re-search-forward php-annotations-re limit t)
+               (when (php-annotations-inside-comment-p (match-beginning 0))
+                 (goto-char (match-end 0))
+                 (throw 'match (match-data))))))))
+    (when match
+      (set-match-data match)
+      t)))
+
+(eval-after-load 'php-mode
+  '(font-lock-add-keywords 'php-mode '((php-annotations-font-lock-find-annotation (2 'php-annotations-annotation-face t)))))
+
+
+
+;;; Correct the behavior of `delete-indentation' by modifying the
+;;; logic of `fixup-whitespace'.
+(defadvice fixup-whitespace (after php-mode-fixup-whitespace)
+  "Remove whitespace before certain characters in PHP mode."
+  (let* ((no-behind-space ";\\|,\\|->\\|::")
+         (no-front-space "->\\|::"))
+    (when (and (eq major-mode 'php-mode)
+               (or (looking-at-p (concat " \\(" no-behind-space "\\)"))
+                   (save-excursion
+                     (forward-char -2)
+                     (looking-at-p no-front-space))))
+      (delete-char 1))))
+
+(ad-activate 'fixup-whitespace)
+
+
+;;;###autoload
+(dolist (pattern '("\\.php[s345t]?\\'" "\\.phtml\\'" "Amkfile" "\\.amk$"))
+  (add-to-list 'auto-mode-alist `(,pattern . php-mode) t))
+
+(provide 'php-mode)
+
+;;; php-mode.el ends here
[from now] 2013/11/19 18:52:29

diff --git a/.emacs.d/ac-comphist.dat b/.emacs.d/ac-comphist.dat
index 60016ca..338efa8 100644
--- a/.emacs.d/ac-comphist.dat
+++ b/.emacs.d/ac-comphist.dat
@@ -1,12 +1,34 @@
-((("line" .
+((("roismall" .
+   [1 0 0 0 0 0 0 0])
+  ("key" .
+   [2 0 0])
+  ("chr" .
+   [1 0 0])
+  ("print" .
+   [2 0 0 0 0])
+  ("thresh" .
+   [1 0 0 0 0 0])
+  ("imshow" .
+   [2 0 0 0 0 0])
+  ("cv2" .
+   [2 0 0])
+  ("Line</key>" .
+   [1 0 0 0 0 0 0 0 0 0])
+  ("<dict>" .
+   [1 0 0 0 0 0])
+  ("term" .
    [1 0 0 0])
-  ("split" .
-   [1 0 0 0 0])
   ("each" .
    [1 0 0 0])
-  ("term" .
+  ("split" .
+   [1 0 0 0 0])
+  ("line" .
    [1 0 0 0])
-  ("<dict>" .
-   [1 0 0 0 0 0])
-  ("Line</key>" .
-   [1 0 0 0 0 0 0 0 0 0])))
+  ("lastRead" .
+   [2 0 0 0 0 0 0 0])
+  ("ReadTweet" .
+   [1 0 0 0 0 0 0 0 0])
+  ("tweet_id" .
+   [2 0 0 0 0 0 0 0])
+  ("unless" .
+   [1 0 0 0 0 0])))
diff --git a/.emacs.d/elisp/php-mode.elc b/.emacs.d/elisp/php-mode.elc
new file mode 100644
index 0000000..d37843c
Binary files /dev/null and b/.emacs.d/elisp/php-mode.elc differ
diff --git a/.emacs.d/elpa/ag-0.20/ag-autoloads.el b/.emacs.d/elpa/ag-0.20/ag-autoloads.el
new file mode 100644
index 0000000..7a9d3ab
--- /dev/null
+++ b/.emacs.d/elpa/ag-0.20/ag-autoloads.el
@@ -0,0 +1,54 @@
+;;; ag-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+
+;;;### (autoloads (ag-regexp-project-at-point ag-project-regexp ag-project
+;;;;;;  ag-regexp ag) "ag" "ag.el" (21096 52407))
+;;; Generated autoloads from ag.el
+
+(autoload 'ag "ag" "\
+Search using ag in a given DIRECTORY for a given search STRING,
+with STRING defaulting to the symbol under point.
+
+\(fn STRING DIRECTORY)" t nil)
+
+(autoload 'ag-regexp "ag" "\
+Search using ag in a given directory for a given regexp.
+
+\(fn STRING DIRECTORY)" t nil)
+
+(autoload 'ag-project "ag" "\
+Guess the root of the current project and search it with ag
+for the given string.
+
+\(fn STRING)" t nil)
+
+(autoload 'ag-project-regexp "ag" "\
+Guess the root of the current project and search it with ag
+for the given regexp.
+
+\(fn REGEXP)" t nil)
+
+(defalias 'ag-project-at-point 'ag-project)
+
+(autoload 'ag-regexp-project-at-point "ag" "\
+Same as ``ag-regexp-project'', but with the search regexp defaulting
+to the symbol under point.
+
+\(fn REGEXP)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("ag-pkg.el") (21096 52407 221456))
+
+;;;***
+
+(provide 'ag-autoloads)
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; ag-autoloads.el ends here
diff --git a/.emacs.d/elpa/ag-0.20/ag-pkg.el b/.emacs.d/elpa/ag-0.20/ag-pkg.el
new file mode 100644
index 0000000..178dfd1
--- /dev/null
+++ b/.emacs.d/elpa/ag-0.20/ag-pkg.el
@@ -0,0 +1 @@
+(define-package "ag" "0.20" "A front-end for ag ('the silver searcher'), the C ack replacement." (quote nil))
diff --git a/.emacs.d/elpa/ag-0.20/ag-pkg.elc b/.emacs.d/elpa/ag-0.20/ag-pkg.elc
new file mode 100644
index 0000000..f18aafc
Binary files /dev/null and b/.emacs.d/elpa/ag-0.20/ag-pkg.elc differ
diff --git a/.emacs.d/elpa/ag-0.20/ag.el b/.emacs.d/elpa/ag-0.20/ag.el
new file mode 100644
index 0000000..01190b5
--- /dev/null
+++ b/.emacs.d/elpa/ag-0.20/ag.el
@@ -0,0 +1,199 @@
+;;; ag.el --- A front-end for ag ('the silver searcher'), the C ack replacement.
+
+;; Copyright (C) 2013 Wilfred Hughes <me@wilfred.me.uk>
+;;
+;; Author: Wilfred Hughes <me@wilfred.me.uk>
+;; Created: 11 January 2013
+;; Version: 0.20
+
+;;; Commentary:
+
+;; This file is heavily based on the excellent ack-and-a-half.el.
+
+;; Usage:
+
+;; Add you to your .emacs.d:
+
+;; (add-to-list 'load-path "/path/to/ag.el") ;; optional
+;; (require 'ag)
+
+;; Alternatively, just install the package from MELPA.
+
+;; If you're using ag 0.14+, which supports --color-match, then you
+;; can add highlighting with:
+
+;; (setq ag-highlight-search t)
+
+;; I like to bind the *-at-point commands to F5 and F6:
+
+;; (global-set-key (kbd "<f5>") 'ag-project)
+;; (global-set-key (kbd "<f6>") 'ag-regexp-project-at-point)
+
+;;; License:
+
+;; This file is not part of GNU Emacs.
+;; However, it is distributed under the same license.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+(defcustom ag-arguments
+  (list "--smart-case" "--nogroup" "--column" "--")
+  "Default arguments passed to ag."
+  :type '(repeat (string))
+  :group 'ag)
+
+(defcustom ag-highlight-search nil
+  "Non-nil means we highlight the current search term in results.
+
+This requires the ag command to support --color-match, which is only in v0.14+"
+  :type 'boolean
+  :group 'ag)
+
+(require 'compile)
+
+;; Although ag results aren't exactly errors, we treat them as errors
+;; so `next-error' and `previous-error' work. However, we ensure our
+;; face inherits from `compilation-info-face' so the results are
+;; styled appropriately.
+(defvar ag-match-face compilation-info-face
+  "Face name to use for ag matches.")
+
+(define-compilation-mode ag-mode "Ag"
+  "Ag results compilation mode"
+  (let ((smbl  'compilation-ag-nogroup)
+        (pttrn '("^\\([^:\n]+?\\):\\([0-9]+\\):\\([0-9]+\\):" 1 2 3)))
+    (set (make-local-variable 'compilation-error-regexp-alist) (list smbl))
+    (set (make-local-variable 'compilation-error-regexp-alist-alist) (list (cons smbl pttrn)))
+    (set (make-local-variable 'compilation-error-face)
+         ag-match-face))
+  (add-hook 'compilation-filter-hook 'ag-filter nil t))
+
+(defun ag/s-join (separator strings)
+  "Join all the strings in STRINGS with SEPARATOR in between."
+  (mapconcat 'identity strings separator))
+
+(defun ag/s-replace (old new s)
+  "Replace all occurrences of OLD in NEW in S."
+  (replace-regexp-in-string (regexp-quote old) new s t t))
+
+(defun ag/shell-quote (string)
+  "Wrap STRING in single quotes, and quote existing single quotes to make shell safe."
+  (concat "'" (ag/s-replace "'" "'\\''" string) "'"))
+
+(defun ag/search (string directory &optional regexp)
+  "Run ag searching for the STRING given in DIRECTORY.
+If REGEXP is non-nil, treat STRING as a regular expression."
+  (let ((default-directory (file-name-as-directory directory))
+        (arguments (if regexp
+                       ag-arguments
+                     (cons "--literal" ag-arguments))))
+    (if ag-highlight-search
+        (setq arguments (append '("--color" "--color-match" "'30;43'") arguments))
+      (setq arguments (append '("--nocolor") arguments)))
+    (unless (file-exists-p default-directory)
+      (error "No such directory %s" default-directory))
+    (compilation-start
+     (ag/s-join " "
+                (append '("ag") arguments (list (ag/shell-quote string))))
+     'ag-mode)))
+
+(defun ag/dwim-at-point ()
+  "If there's an active selection, return that.
+Otherwise, get the symbol at point."
+  (if (use-region-p)
+      (buffer-substring-no-properties (region-beginning) (region-end))
+    (if (symbol-at-point)
+        (symbol-name (symbol-at-point)))))
+
+(autoload 'vc-git-root "vc-git")
+(autoload 'vc-svn-root "vc-svn")
+
+(defun ag/project-root (file-path)
+  "Guess the project root of the given FILE-PATH."
+  (or (vc-git-root file-path)
+      (vc-svn-root file-path)
+      file-path))
+
+;;;###autoload
+(defun ag (string directory)
+  "Search using ag in a given DIRECTORY for a given search STRING,
+with STRING defaulting to the symbol under point."
+   (interactive (list (read-from-minibuffer "Search string: " (ag/dwim-at-point))
+                      (read-directory-name "Directory: ")))
+   (ag/search string directory))
+
+;;;###autoload
+(defun ag-regexp (string directory)
+  "Search using ag in a given directory for a given regexp."
+  (interactive "sSearch regexp: \nDDirectory: ")
+  (ag/search string directory t))
+
+;;;###autoload
+(defun ag-project (string)
+  "Guess the root of the current project and search it with ag
+for the given string."
+  (interactive (list (read-from-minibuffer "Search string: " (ag/dwim-at-point))))
+  (ag/search string (ag/project-root default-directory)))
+
+;;;###autoload
+(defun ag-project-regexp (regexp)
+  "Guess the root of the current project and search it with ag
+for the given regexp."
+  (interactive "sSearch regexp: ")
+  (ag/search regexp (ag/project-root default-directory) t))
+
+(autoload 'symbol-at-point "thingatpt")
+
+;;;###autoload
+(defalias 'ag-project-at-point 'ag-project)
+
+;;;###autoload
+(defun ag-regexp-project-at-point (regexp)
+  "Same as ``ag-regexp-project'', but with the search regexp defaulting
+to the symbol under point."
+   (interactive (list (read-from-minibuffer "Search regexp: " (ag/dwim-at-point))))
+
+   (ag/search regexp (ag/project-root default-directory) t))
+
+;; Taken from grep-filter, just changed the color regex.
+(defun ag-filter ()
+  "Handle match highlighting escape sequences inserted by the ag process.
+This function is called from `compilation-filter-hook'."
+  (when ag-highlight-search
+    (save-excursion
+      (forward-line 0)
+      (let ((end (point)) beg)
+        (goto-char compilation-filter-start)
+        (forward-line 0)
+        (setq beg (point))
+        ;; Only operate on whole lines so we don't get caught with part of an
+        ;; escape sequence in one chunk and the rest in another.
+        (when (< (point) end)
+          (setq end (copy-marker end))
+          ;; Highlight ag matches and delete marking sequences.
+          (while (re-search-forward "\033\\[30;43m\\(.*?\\)\033\\[[0-9]*m" end 1)
+            (replace-match (propertize (match-string 1)
+                                       'face nil 'font-lock-face ag-match-face)
+                           t t))
+          ;; Delete all remaining escape sequences
+          (goto-char beg)
+          (while (re-search-forward "\033\\[[0-9;]*[mK]" end 1)
+            (replace-match "" t t)))))))
+
+(provide 'ag)
+;;; ag.el ends here
diff --git a/.emacs.d/elpa/ag-0.20/ag.elc b/.emacs.d/elpa/ag-0.20/ag.elc
new file mode 100644
index 0000000..42f2786
Binary files /dev/null and b/.emacs.d/elpa/ag-0.20/ag.elc differ
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 76fed38..731112c 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -568,6 +568,13 @@ static char * arrow_right[] = {
   (when (executable-find "git")
     (remove-hook 'after-save-hook 'gitnow-after-save-hook)))

+;; http://superuser.com/a/621290
+;; Do not use rebase-mode.
+;; The rebase-mode in emacs is read-only and not use-friendly.
+(setq auto-mode-alist (delete '("git-rebase-todo" . rebase-mode)
+                              auto-mode-alist))
+
+
 ;; http://pokutech.hatenablog.com/entry/2012/07/14/233900
 ;; バッファローカルに，shell-commandを実行する一時的なafter-save-hookを追加するelispを追加する．
 ;; 動作しない．
@@ -584,4 +591,15 @@ static char * arrow_right[] = {

 ;; 最近開いたファイル機能を有効化
 ;; 開くときはM-x recentf-open-files
-(recentf-mode 1)
\ No newline at end of file
+(recentf-mode 1)
+
+;; server start for emacs-client
+(require 'server)
+(unless (server-running-p)
+  (server-start))
+
+;; php-mode
+(when (require 'php-mode nil t)
+  (add-to-list 'auto-mode-alist '("\\.ctp\\'" . php-mode))
+  (setq php-search-url "http://jp.php.net/ja/")
+  (setq php-manual-url "http://jp.php.net/manual/ja/"))
[from now] 2013/11/19 18:54:31

diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 731112c..93ff9cf 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -603,3 +603,13 @@ static char * arrow_right[] = {
   (add-to-list 'auto-mode-alist '("\\.ctp\\'" . php-mode))
   (setq php-search-url "http://jp.php.net/ja/")
   (setq php-manual-url "http://jp.php.net/manual/ja/"))
+
+;; php-modeのインデント設定
+(defun php-indent-hook ()
+  (setq indent-tabs-mode nil)
+  (setq c-basic-offset 4)
+  ;; (c-set-ofset 'case-label' '+) ; swtich文のcaseラベル
+  (c-set-offset 'arglist-intro '+) ; 配列の最初の要素が改行した場合
+  (c-set-offset 'arglist-close 0)) ; 配列のとじカッコ
+
+(add-hook 'php-mode-hook 'php-indent-hook)
[from now] 2013/11/19 19:01:46

diff --git a/.emacs.d/ac-comphist.dat b/.emacs.d/ac-comphist.dat
index 338efa8..00dcd58 100644
--- a/.emacs.d/ac-comphist.dat
+++ b/.emacs.d/ac-comphist.dat
@@ -1,34 +1,34 @@
-((("roismall" .
-   [1 0 0 0 0 0 0 0])
-  ("key" .
-   [2 0 0])
-  ("chr" .
-   [1 0 0])
-  ("print" .
-   [2 0 0 0 0])
-  ("thresh" .
-   [1 0 0 0 0 0])
-  ("imshow" .
-   [2 0 0 0 0 0])
-  ("cv2" .
-   [2 0 0])
-  ("Line</key>" .
-   [1 0 0 0 0 0 0 0 0 0])
-  ("<dict>" .
+((("unless" .
    [1 0 0 0 0 0])
-  ("term" .
-   [1 0 0 0])
-  ("each" .
-   [1 0 0 0])
-  ("split" .
-   [1 0 0 0 0])
-  ("line" .
-   [1 0 0 0])
-  ("lastRead" .
+  ("tweet_id" .
    [2 0 0 0 0 0 0 0])
   ("ReadTweet" .
    [1 0 0 0 0 0 0 0 0])
-  ("tweet_id" .
+  ("lastRead" .
    [2 0 0 0 0 0 0 0])
-  ("unless" .
-   [1 0 0 0 0 0])))
+  ("line" .
+   [1 0 0 0])
+  ("split" .
+   [1 0 0 0 0])
+  ("each" .
+   [1 0 0 0])
+  ("term" .
+   [1 0 0 0])
+  ("<dict>" .
+   [1 0 0 0 0 0])
+  ("Line</key>" .
+   [1 0 0 0 0 0 0 0 0 0])
+  ("cv2" .
+   [2 0 0])
+  ("imshow" .
+   [2 0 0 0 0 0])
+  ("thresh" .
+   [1 0 0 0 0 0])
+  ("print" .
+   [2 0 0 0 0])
+  ("chr" .
+   [1 0 0])
+  ("key" .
+   [2 0 0])
+  ("roismall" .
+   [1 0 0 0 0 0 0 0])))
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 93ff9cf..ff2f8b9 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -604,12 +604,3 @@ static char * arrow_right[] = {
   (setq php-search-url "http://jp.php.net/ja/")
   (setq php-manual-url "http://jp.php.net/manual/ja/"))

-;; php-modeのインデント設定
-(defun php-indent-hook ()
-  (setq indent-tabs-mode nil)
-  (setq c-basic-offset 4)
-  ;; (c-set-ofset 'case-label' '+) ; swtich文のcaseラベル
-  (c-set-offset 'arglist-intro '+) ; 配列の最初の要素が改行した場合
-  (c-set-offset 'arglist-close 0)) ; 配列のとじカッコ
-
-(add-hook 'php-mode-hook 'php-indent-hook)
[from now] 2013/11/19 19:02:21

diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index ff2f8b9..c5c8ec8 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -604,3 +604,12 @@ static char * arrow_right[] = {
   (setq php-search-url "http://jp.php.net/ja/")
   (setq php-manual-url "http://jp.php.net/manual/ja/"))

+;; php-modeのインデント設定
+(defun php-indent-hook ()
+  (setq indent-tabs-mode nil)
+  (setq c-basic-offset 4)
+  ;; (c-set-ofset 'case-label' '+) ; swtich文のcaseラベル
+  (c-set-offset 'arglist-intro '+) ; 配列の最初の要素が改行した場合
+  (c-set-offset 'arglist-close 0)) ; 配列のとじカッコ
+
+(add-hook 'php-mode-hook 'php-indent-hook)
[from now] 2013/11/19 19:02:32

diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index c5c8ec8..27564d6 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -598,18 +598,3 @@ static char * arrow_right[] = {
 (unless (server-running-p)
   (server-start))

-;; php-mode
-(when (require 'php-mode nil t)
-  (add-to-list 'auto-mode-alist '("\\.ctp\\'" . php-mode))
-  (setq php-search-url "http://jp.php.net/ja/")
-  (setq php-manual-url "http://jp.php.net/manual/ja/"))
-
-;; php-modeのインデント設定
-(defun php-indent-hook ()
-  (setq indent-tabs-mode nil)
-  (setq c-basic-offset 4)
-  ;; (c-set-ofset 'case-label' '+) ; swtich文のcaseラベル
-  (c-set-offset 'arglist-intro '+) ; 配列の最初の要素が改行した場合
-  (c-set-offset 'arglist-close 0)) ; 配列のとじカッコ
-
-(add-hook 'php-mode-hook 'php-indent-hook)
[from now] 2013/11/19 19:04:33

diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 27564d6..c5c8ec8 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -598,3 +598,18 @@ static char * arrow_right[] = {
 (unless (server-running-p)
   (server-start))

+;; php-mode
+(when (require 'php-mode nil t)
+  (add-to-list 'auto-mode-alist '("\\.ctp\\'" . php-mode))
+  (setq php-search-url "http://jp.php.net/ja/")
+  (setq php-manual-url "http://jp.php.net/manual/ja/"))
+
+;; php-modeのインデント設定
+(defun php-indent-hook ()
+  (setq indent-tabs-mode nil)
+  (setq c-basic-offset 4)
+  ;; (c-set-ofset 'case-label' '+) ; swtich文のcaseラベル
+  (c-set-offset 'arglist-intro '+) ; 配列の最初の要素が改行した場合
+  (c-set-offset 'arglist-close 0)) ; 配列のとじカッコ
+
+(add-hook 'php-mode-hook 'php-indent-hook)
[from now] 2013/11/19 19:07:40

diff --git a/.emacs.d/ac-comphist.dat b/.emacs.d/ac-comphist.dat
index 00dcd58..338efa8 100644
--- a/.emacs.d/ac-comphist.dat
+++ b/.emacs.d/ac-comphist.dat
@@ -1,34 +1,34 @@
-((("unless" .
+((("roismall" .
+   [1 0 0 0 0 0 0 0])
+  ("key" .
+   [2 0 0])
+  ("chr" .
+   [1 0 0])
+  ("print" .
+   [2 0 0 0 0])
+  ("thresh" .
    [1 0 0 0 0 0])
-  ("tweet_id" .
-   [2 0 0 0 0 0 0 0])
-  ("ReadTweet" .
-   [1 0 0 0 0 0 0 0 0])
-  ("lastRead" .
-   [2 0 0 0 0 0 0 0])
-  ("line" .
+  ("imshow" .
+   [2 0 0 0 0 0])
+  ("cv2" .
+   [2 0 0])
+  ("Line</key>" .
+   [1 0 0 0 0 0 0 0 0 0])
+  ("<dict>" .
+   [1 0 0 0 0 0])
+  ("term" .
    [1 0 0 0])
-  ("split" .
-   [1 0 0 0 0])
   ("each" .
    [1 0 0 0])
-  ("term" .
+  ("split" .
+   [1 0 0 0 0])
+  ("line" .
    [1 0 0 0])
-  ("<dict>" .
-   [1 0 0 0 0 0])
-  ("Line</key>" .
-   [1 0 0 0 0 0 0 0 0 0])
-  ("cv2" .
-   [2 0 0])
-  ("imshow" .
-   [2 0 0 0 0 0])
-  ("thresh" .
-   [1 0 0 0 0 0])
-  ("print" .
-   [2 0 0 0 0])
-  ("chr" .
-   [1 0 0])
-  ("key" .
-   [2 0 0])
-  ("roismall" .
-   [1 0 0 0 0 0 0 0])))
+  ("lastRead" .
+   [2 0 0 0 0 0 0 0])
+  ("ReadTweet" .
+   [1 0 0 0 0 0 0 0 0])
+  ("tweet_id" .
+   [2 0 0 0 0 0 0 0])
+  ("unless" .
+   [1 0 0 0 0 0])))
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index c5c8ec8..1186c86 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -600,16 +600,4 @@ static char * arrow_right[] = {

 ;; php-mode
 (when (require 'php-mode nil t)
-  (add-to-list 'auto-mode-alist '("\\.ctp\\'" . php-mode))
-  (setq php-search-url "http://jp.php.net/ja/")
-  (setq php-manual-url "http://jp.php.net/manual/ja/"))
-
-;; php-modeのインデント設定
-(defun php-indent-hook ()
-  (setq indent-tabs-mode nil)
-  (setq c-basic-offset 4)
-  ;; (c-set-ofset 'case-label' '+) ; swtich文のcaseラベル
-  (c-set-offset 'arglist-intro '+) ; 配列の最初の要素が改行した場合
-  (c-set-offset 'arglist-close 0)) ; 配列のとじカッコ
-
-(add-hook 'php-mode-hook 'php-indent-hook)
+  )
\ No newline at end of file
[from now] 2013/11/19 19:11:32

diff --git a/.emacs.d/elisp/php-mode.el b/.emacs.d/elisp/php-mode.el
index 0feb57c..82253f4 100644
--- a/.emacs.d/elisp/php-mode.el
+++ b/.emacs.d/elisp/php-mode.el
@@ -711,15 +711,6 @@ the string HEREDOC-START."
   (syntax-propertize-rules
    (php-heredoc-start-re (0 (ignore (php-heredoc-syntax))))))

-(defun php-heredoc-syntax ()
-  "Mark the boundaries of searched heredoc."
-  (goto-char (match-beginning 0))
-  (c-put-char-property (point) 'syntax-table (string-to-syntax "|"))
-  (if (re-search-forward (php-heredoc-end-re (match-string 0)) nil t)
-      (goto-char (match-end 1))
-    ;; Did not find the delimiter so go to the end of the buffer.
-    (goto-char (point-max)))
-  (c-put-char-property (1- (point)) 'syntax-table (string-to-syntax "|")))

 (defun php-syntax-propertize-extend-region (start end)
   "Extend the propertize region of START falls inside a heredoc."
[from now] 2013/11/19 19:11:43

diff --git a/.emacs.d/elisp/php-mode.el b/.emacs.d/elisp/php-mode.el
index 82253f4..0feb57c 100644
--- a/.emacs.d/elisp/php-mode.el
+++ b/.emacs.d/elisp/php-mode.el
@@ -711,6 +711,15 @@ the string HEREDOC-START."
   (syntax-propertize-rules
    (php-heredoc-start-re (0 (ignore (php-heredoc-syntax))))))

+(defun php-heredoc-syntax ()
+  "Mark the boundaries of searched heredoc."
+  (goto-char (match-beginning 0))
+  (c-put-char-property (point) 'syntax-table (string-to-syntax "|"))
+  (if (re-search-forward (php-heredoc-end-re (match-string 0)) nil t)
+      (goto-char (match-end 1))
+    ;; Did not find the delimiter so go to the end of the buffer.
+    (goto-char (point-max)))
+  (c-put-char-property (1- (point)) 'syntax-table (string-to-syntax "|")))

 (defun php-syntax-propertize-extend-region (start end)
   "Extend the propertize region of START falls inside a heredoc."
[from now] 2013/11/19 19:13:53

diff --git a/.emacs.d/ac-comphist.dat b/.emacs.d/ac-comphist.dat
index 338efa8..00dcd58 100644
--- a/.emacs.d/ac-comphist.dat
+++ b/.emacs.d/ac-comphist.dat
@@ -1,34 +1,34 @@
-((("roismall" .
-   [1 0 0 0 0 0 0 0])
-  ("key" .
-   [2 0 0])
-  ("chr" .
-   [1 0 0])
-  ("print" .
-   [2 0 0 0 0])
-  ("thresh" .
-   [1 0 0 0 0 0])
-  ("imshow" .
-   [2 0 0 0 0 0])
-  ("cv2" .
-   [2 0 0])
-  ("Line</key>" .
-   [1 0 0 0 0 0 0 0 0 0])
-  ("<dict>" .
+((("unless" .
    [1 0 0 0 0 0])
-  ("term" .
-   [1 0 0 0])
-  ("each" .
-   [1 0 0 0])
-  ("split" .
-   [1 0 0 0 0])
-  ("line" .
-   [1 0 0 0])
-  ("lastRead" .
+  ("tweet_id" .
    [2 0 0 0 0 0 0 0])
   ("ReadTweet" .
    [1 0 0 0 0 0 0 0 0])
-  ("tweet_id" .
+  ("lastRead" .
    [2 0 0 0 0 0 0 0])
-  ("unless" .
-   [1 0 0 0 0 0])))
+  ("line" .
+   [1 0 0 0])
+  ("split" .
+   [1 0 0 0 0])
+  ("each" .
+   [1 0 0 0])
+  ("term" .
+   [1 0 0 0])
+  ("<dict>" .
+   [1 0 0 0 0 0])
+  ("Line</key>" .
+   [1 0 0 0 0 0 0 0 0 0])
+  ("cv2" .
+   [2 0 0])
+  ("imshow" .
+   [2 0 0 0 0 0])
+  ("thresh" .
+   [1 0 0 0 0 0])
+  ("print" .
+   [2 0 0 0 0])
+  ("chr" .
+   [1 0 0])
+  ("key" .
+   [2 0 0])
+  ("roismall" .
+   [1 0 0 0 0 0 0 0])))
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 1186c86..af74b11 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -598,6 +598,6 @@ static char * arrow_right[] = {
 (unless (server-running-p)
   (server-start))

-;; php-mode
-(when (require 'php-mode nil t)
-  )
\ No newline at end of file
+;; php-modeを入れたが，
+;;; Symbol's function definition is void: php-heredoc-syntax
+;; のエラーが出てしまうため削除．
\ No newline at end of file
[from now] 2013/11/20 10:13:58

diff --git a/.emacs.d/elisp/php-mode-improved.el b/.emacs.d/elisp/php-mode-improved.el
new file mode 100644
index 0000000..90781db
--- /dev/null
+++ b/.emacs.d/elisp/php-mode-improved.el
@@ -0,0 +1,1392 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head><title>EmacsWiki: php-mode-improved.el</title><link rel="alternate" type="application/wiki" title="Edit this page" href="http://www.emacswiki.org/emacs?action=edit;id=php-mode-improved.el" />
+<link type="text/css" rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" />
+<link type="text/css" rel="stylesheet" href="/css/bootstrap.css" />
+<meta name="robots" content="INDEX,FOLLOW" /><link rel="alternate" type="application/rss+xml" title="EmacsWiki" href="http://www.emacswiki.org/emacs?action=rss" /><link rel="alternate" type="application/rss+xml" title="EmacsWiki: php-mode-improved.el" href="http://www.emacswiki.org/emacs?action=rss;rcidonly=php-mode-improved.el" />
+<link rel="alternate" type="application/rss+xml"
+      title="Emacs Wiki with page content"
+      href="http://www.emacswiki.org/emacs/full.rss" />
+<link rel="alternate" type="application/rss+xml"
+      title="Emacs Wiki with page content and diff"
+      href="http://www.emacswiki.org/emacs/full-diff.rss" />
+<link rel="alternate" type="application/rss+xml"
+      title="Emacs Wiki including minor differences"
+      href="http://www.emacswiki.org/emacs/minor-edits.rss" />
+<link rel="alternate" type="application/rss+xml"
+      title="Changes for php-mode-improved.el only"
+      href="http://www.emacswiki.org/emacs?action=rss;rcidonly=php-mode-improved.el" /><meta name="viewport" content="width=device-width" />
+<script type="text/javascript" src="/outliner.0.5.0.62-toc.js"></script>
+<script type="text/javascript">
+
+  function addOnloadEvent(fnc) {
+    if ( typeof window.addEventListener != "undefined" )
+      window.addEventListener( "load", fnc, false );
+    else if ( typeof window.attachEvent != "undefined" ) {
+      window.attachEvent( "onload", fnc );
+    }
+    else {
+      if ( window.onload != null ) {
+	var oldOnload = window.onload;
+	window.onload = function ( e ) {
+	  oldOnload( e );
+	  window[fnc]();
+	};
+      }
+      else
+	window.onload = fnc;
+    }
+  }
+
+  var initToc=function() {
+
+    var outline = HTML5Outline(document.body);
+    if (outline.sections.length == 1) {
+      outline.sections = outline.sections[0].sections;
+    }
+
+    if (outline.sections.length > 1
+	|| outline.sections.length == 1
+           && outline.sections[0].sections.length > 0) {
+
+      var toc = document.getElementById('toc');
+
+      if (!toc) {
+	var divs = document.getElementsByTagName('div');
+	for (var i = 0; i < divs.length; i++) {
+	  if (divs[i].getAttribute('class') == 'toc') {
+	    toc = divs[i];
+	    break;
+	  }
+	}
+      }
+
+      if (!toc) {
+	var h2 = document.getElementsByTagName('h2')[0];
+	if (h2) {
+	  toc = document.createElement('div');
+	  toc.setAttribute('class', 'toc');
+	  h2.parentNode.insertBefore(toc, h2);
+	}
+      }
+
+      if (toc) {
+        var html = outline.asHTML(true);
+        toc.innerHTML = html;
+      }
+    }
+  }
+
+  addOnloadEvent(initToc);
+  </script>
+
+<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
+<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/js/bootstrap.min.js"></script>
+<script src="http://emacswiki.org/emacs/emacs-bootstrap.js"></script>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body class="http://www.emacswiki.org/emacs"><div class="header"><span class="gotobar bar"><a class="local" href="http://www.emacswiki.org/emacs/SiteMap">SiteMap</a> <a class="local" href="http://www.emacswiki.org/emacs/Search">Search</a> <a class="local" href="http://www.emacswiki.org/emacs/ElispArea">ElispArea</a> <a class="local" href="http://www.emacswiki.org/emacs/HowTo">HowTo</a> <a class="local" href="http://www.emacswiki.org/emacs/Glossary">Glossary</a> <a class="local" href="http://www.emacswiki.org/emacs/RecentChanges">RecentChanges</a> <a class="local" href="http://www.emacswiki.org/emacs/News">News</a> <a class="local" href="http://www.emacswiki.org/emacs/Problems">Problems</a> <a class="local" href="http://www.emacswiki.org/emacs/Suggestions">Suggestions</a> </span><h1><a title="Click to search for references to this page" rel="nofollow" href="http://www.emacswiki.org/emacs?search=%22php-mode-improved%5c.el%22">php-mode-improved.el</a></h1></div><div class="wrapper"><div class="content browse"><p class="download"><a href="download/php-mode-improved.el">Download</a></p><pre class="code"><span class="linecomment">;;; php-mode.el --- major mode for editing PHP code</span>
+
+<span class="linecomment">;; This is a version of the php-mode from http://php-mode.sourceforge.net that</span>
+<span class="linecomment">;; fixes a few bugs which make using php-mode much more palatable, namely:</span>
+<span class="linecomment">;; </span>
+<span class="linecomment">;; 1. New customisation options for some of the syntax highlighting</span>
+<span class="linecomment">;;   features. I personally use the 'Gauchy' level of syntax</span>
+<span class="linecomment">;;   highlighting -- I want variables and function calls fontified --</span>
+<span class="linecomment">;;   but there were several very annoying "features" in this level of</span>
+<span class="linecomment">;;   syntax highlighting, particularly the ones that warn you about</span>
+<span class="linecomment">;;   perfectly valid code. I've added:</span>
+<span class="linecomment">;; </span>
+<span class="linecomment">;;   * `php-mode-dollar-property-warning', which, if non-nil, warns on</span>
+<span class="linecomment">;;     $foo-&gt;$bar. (Default is nil.)</span>
+<span class="linecomment">;;   * `php-mode-dot-property-warning', which, if non-nil, warns on</span>
+<span class="linecomment">;;     $foo.bar. (Default is nil.)</span>
+<span class="linecomment">;;   * `php-mode-warn-on-unmatches', which, if non-nil, warns on</span>
+<span class="linecomment">;;     "everything else". (Default is nil.)</span>
+<span class="linecomment">;;   * `php-mode-warn-if-mumamo-off', which, if nil, suppresses the</span>
+<span class="linecomment">;;     once-per-file warning about indenting with mumamo-mode turned</span>
+<span class="linecomment">;;     off. (Default is t)</span>
+<span class="linecomment">;; </span>
+<span class="linecomment">;; 2. Bugfix in `php-show-arglist': this function no longer jumps to the</span>
+<span class="linecomment">;;   function definition if that definition is in the current buffer.</span>
+<span class="linecomment">;; </span>
+<span class="linecomment">;; 3. Bugfix: 'class' keywords at the beginning of a line are now</span>
+<span class="linecomment">;;   correctly fontified.</span>
+<span class="linecomment">;; </span>
+<span class="linecomment">;; This has been submitted to the php-mode maintainer, but I've not yet had a</span>
+<span class="linecomment">;; response.</span>
+<span class="linecomment">;;</span>
+<span class="linecomment">;; This was branched from the php-mode in nxhtml-mode, so if you have problems,</span>
+<span class="linecomment">;; download the latest nxhtml-mode, and replace related/php-mode.el in the</span>
+<span class="linecomment">;; nxhtml distribution with this file.</span>
+<span class="linecomment">;; </span>
+<span class="linecomment">;; -- David House, dmhouse@gmail.com</span>
+
+<span class="linecomment">;; Copyright (C) 1999, 2000, 2001, 2003, 2004 Turadg Aleahmad</span>
+<span class="linecomment">;;               2008 Aaron S. Hawley</span>
+
+<span class="linecomment">;; Maintainer: Aaron S. Hawley &lt;ashawley at users.sourceforge.net&gt;</span>
+<span class="linecomment">;; Author: Turadg Aleahmad, 1999-2004</span>
+<span class="linecomment">;; Keywords: php languages oop</span>
+<span class="linecomment">;; Created: 1999-05-17</span>
+<span class="linecomment">;; Modified: 2008-01-25T22:25:26+0100 Fri</span>
+<span class="linecomment">;; X-URL:   http://php-mode.sourceforge.net/</span>
+
+(defconst php-mode-version-number "<span class="quote">1.4.1a-nxhtml</span>"
+  "<span class="quote">PHP Mode version number.</span>")
+
+<span class="linecomment">;;; License</span>
+
+<span class="linecomment">;; This file is free software; you can redistribute it and/or</span>
+<span class="linecomment">;; modify it under the terms of the GNU General Public License</span>
+<span class="linecomment">;; as published by the Free Software Foundation; either version 3</span>
+<span class="linecomment">;; of the License, or (at your option) any later version.</span>
+
+<span class="linecomment">;; This file is distributed in the hope that it will be useful,</span>
+<span class="linecomment">;; but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
+<span class="linecomment">;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
+<span class="linecomment">;; GNU General Public License for more details.</span>
+
+<span class="linecomment">;; You should have received a copy of the GNU General Public License</span>
+<span class="linecomment">;; along with this file; if not, write to the Free Software</span>
+<span class="linecomment">;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA</span>
+<span class="linecomment">;; 02110-1301, USA.</span>
+
+<span class="linecomment">;;; Usage</span>
+
+<span class="linecomment">;; Put this file in your Emacs lisp path (eg. site-lisp) and add to</span>
+<span class="linecomment">;; your .emacs file:</span>
+<span class="linecomment">;;</span>
+<span class="linecomment">;;   (require 'php-mode)</span>
+
+<span class="linecomment">;; To use abbrev-mode, add lines like this:</span>
+<span class="linecomment">;;   (add-hook 'php-mode-hook</span>
+<span class="linecomment">;;     '(lambda () (define-abbrev php-mode-abbrev-table "ex" "extends")))</span>
+
+<span class="linecomment">;; To make php-mode compatible with html-mode, see http://php-mode.sf.net</span>
+
+<span class="linecomment">;; Many options available under Help:Customize</span>
+<span class="linecomment">;; Options specific to php-mode are in</span>
+<span class="linecomment">;;  Programming/Languages/Php</span>
+<span class="linecomment">;; Since it inherits much functionality from c-mode, look there too</span>
+<span class="linecomment">;;  Programming/Languages/C</span>
+
+<span class="linecomment">;;; Commentary:</span>
+
+<span class="linecomment">;; PHP mode is a major mode for editing PHP 3 and 4 source code.  It's</span>
+<span class="linecomment">;; an extension of C mode; thus it inherits all C mode's navigation</span>
+<span class="linecomment">;; functionality.  But it colors according to the PHP grammar and indents</span>
+<span class="linecomment">;; according to the PEAR coding guidelines.  It also includes a couple</span>
+<span class="linecomment">;; handy IDE-type features such as documentation search and a source</span>
+<span class="linecomment">;; and class browser.</span>
+
+
+<span class="linecomment">;;; Contributors: (in chronological order)</span>
+
+<span class="linecomment">;; Juanjo, Torsten Martinsen, Vinai Kopp, Sean Champ, Doug Marcey,</span>
+<span class="linecomment">;; Kevin Blake, Rex McMaster, Mathias Meyer, Boris Folgmann, Roland</span>
+<span class="linecomment">;; Rosenfeld, Fred Yankowski, Craig Andrews, John Keller, Ryan</span>
+<span class="linecomment">;; Sammartino, ppercot, Valentin Funk, Stig Bakken, Gregory Stark,</span>
+<span class="linecomment">;; Chris Morris, Nils Rennebarth, Gerrit Riessen, Eric Mc Sween,</span>
+<span class="linecomment">;; Ville Skytta, Giacomo Tesio, Lennart Borgman, Stefan Monnier,</span>
+<span class="linecomment">;; Aaron S. Hawley, Ian Eure, Bill Lovett, David House</span>
+
+<span class="linecomment">;;; Changelog:</span>
+
+<span class="linecomment">;; 1.4.1a-nxhtml</span>
+<span class="linecomment">;;   Made underscore be part of identifiers.</span>
+<span class="linecomment">;;</span>
+<span class="linecomment">;; 1.4.1-nxhtml</span>
+<span class="linecomment">;;   Added php-mode-to-use.</span>
+
+<span class="linecomment">;; 1.4.1</span>
+<span class="linecomment">;;   Modified `php-check-html-for-indentation' to check for multiple</span>
+<span class="linecomment">;;   mode support libraries. (Lennart Borgman)</span>
+<span class="linecomment">;;</span>
+<span class="linecomment">;; 1.4</span>
+<span class="linecomment">;;   Updated GNU GPL to version 3.  Ported to Emacs 22 (CC mode</span>
+<span class="linecomment">;;   5.31). M-x php-mode-version shows version.  Provide end-of-defun</span>
+<span class="linecomment">;;   beginning-of-defun functionality. Support add-log library.</span>
+<span class="linecomment">;;   Fix __CLASS__ constant (Ian Eure).  Allow imenu to see visibility</span>
+<span class="linecomment">;;   declarations -- "private", "public", "protected". (Bill Lovett)</span>
+<span class="linecomment">;;</span>
+<span class="linecomment">;; 1.3</span>
+<span class="linecomment">;;   Changed the definition of # using a tip from Stefan</span>
+<span class="linecomment">;;   Monnier to correct highlighting and indentation. (Lennart Borgman)</span>
+<span class="linecomment">;;   Changed the highlighting of the HTML part. (Lennart Borgman)</span>
+<span class="linecomment">;;</span>
+<span class="linecomment">;; 1.2</span>
+<span class="linecomment">;;   Implemented php-show-arglist, C-. (Engelke Eschner)</span>
+<span class="linecomment">;;   Implemented php-complete-function, M-tab (Engelke Eschner)</span>
+<span class="linecomment">;;   Re-enabled # comment detection in GNU Emacs (Urban Müller)</span>
+<span class="linecomment">;;   Fixed some keybindings and default settings (Engelke Eschner)</span>
+<span class="linecomment">;;</span>
+<span class="linecomment">;; 1.1</span>
+<span class="linecomment">;;   Added PHP5 support (Giacomo Tesio)</span>
+<span class="linecomment">;;     known problem: doesn't highlight after first 'implements'</span>
+<span class="linecomment">;;   Better XEmacs compatibility (imenu, regexp, and comments!) (Ville Skytta)</span>
+<span class="linecomment">;;   Improvement to php-conditional-key regexp (Eric Mc Sween)</span>
+
+<span class="linecomment">;; 1.05</span>
+<span class="linecomment">;;   Incorporated speedbar defs by Gerrit Riessen</span>
+<span class="linecomment">;;   Add "foreach" to conditional introducing keywords (Nils Rennebarth)</span>
+<span class="linecomment">;;   Cleared the Changelog</span>
+<span class="linecomment">;;   Moved contribution credits into comments above</span>
+
+
+<span class="linecomment">;;; Code:</span>
+
+(require 'speedbar)
+(require 'font-lock)
+(require 'cc-mode)
+(require 'custom)
+(require 'etags)
+(eval-when-compile
+  (require 'regexp-opt))
+
+<span class="linecomment">;; Local variables</span>
+(defgroup php nil
+  "<span class="quote">Major mode `php-mode' for editing PHP code.</span>"
+  :prefix "<span class="quote">php-</span>"
+  :group 'languages)
+
+(defcustom php-default-face 'default
+  "<span class="quote">Default face in `php-mode' buffers.</span>"
+  :type 'face
+  :group 'php)
+
+(defcustom php-speedbar-config t
+  "<span class="quote">When set to true automatically configures Speedbar to observe PHP files.\
+Ignores php-file patterns option; fixed to expression \"\\.\\(inc\\|php[s34]?\\)\"</span>"
+  :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (if (and val (boundp 'speedbar))
+             (speedbar-add-supported-extension
+              "<span class="quote">\\.\\(inc\\|php[s34]?\\|phtml\\)</span>")))
+  :group 'php)
+
+(defcustom php-mode-speedbar-open nil
+  "<span class="quote">Normally `php-mode' starts with the speedbar closed.\
+Turning this on will open it whenever `php-mode' is loaded.</span>"
+  :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (when val
+             (speedbar 1)))
+  :group 'php)
+
+(defcustom php-manual-url "<span class="quote">http://www.php.net/manual/en/</span>"
+  "<span class="quote">URL at which to find PHP manual.\
+You can replace \"en\" with your ISO language code.</span>"
+  :type 'string
+  :group 'php)
+
+(defcustom php-search-url "<span class="quote">http://www.php.net/</span>"
+  "<span class="quote">URL at which to search for documentation on a word</span>"
+  :type 'string
+  :group 'php)
+
+(defcustom php-completion-file "<span class="quote"></span>"
+  "<span class="quote">Path to the file which contains the function names known to PHP</span>"
+  :type 'string
+  :group 'php)
+
+(defcustom php-manual-path "<span class="quote"></span>"
+  "<span class="quote">Path to the directory which contains the PHP manual</span>"
+  :type 'string
+  :group 'php)
+
+<span class="linecomment">;;;###autoload</span>
+(defcustom php-mode-to-use
+  (progn
+    (require 'mumamo nil t)
+    (if (fboundp 'nxhtml-mumamo-turn-on)
+        'nxhtml-mumamo-turn-on
+      (if (fboundp 'html-mumamo-turn-on)
+          'html-mumamo-turn-on
+        'php-mode)))
+  "<span class="quote">Major mode turn on function to use for php files.</span>"
+  :type 'function
+  :group 'php)
+
+<span class="linecomment">;;;###autoload</span>
+(defcustom php-file-patterns '("<span class="quote">\\.php[s34]?\\'</span>" "<span class="quote">\\.phtml\\'</span>" "<span class="quote">\\.inc\\'</span>")
+  "<span class="quote">List of file patterns for which to automatically invoke `php-mode'.</span>"
+  :type '(repeat (regexp :tag "<span class="quote">Pattern</span>"))
+  :set-after '(php-mode-to-use)
+  :set (lambda (sym val)
+         (set-default sym val)
+         (let ((php-file-patterns-temp val))
+           (while php-file-patterns-temp
+             (add-to-list 'auto-mode-alist
+                          (cons (car php-file-patterns-temp) php-mode-to-use))
+             (setq php-file-patterns-temp (cdr php-file-patterns-temp)))))
+  :group 'php)
+
+(defcustom php-mode-hook nil
+  "<span class="quote">List of functions to be executed on entry to `php-mode'.</span>"
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-pear-hook nil
+  "<span class="quote">Hook called when a PHP PEAR file is opened with `php-mode'.</span>"
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-force-pear nil
+  "<span class="quote">Normally PEAR coding rules are enforced only when the filename contains \"PEAR\"\
+Turning this on will force PEAR rules on all PHP files.</span>"
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-mode-dollar-property-warning nil
+  "<span class="quote">If non-`nil', warn about expressions like $foo-&gt;$bar where you
+might have meant $foo-&gt;bar. Defaults to `nil' since this is valid
+code.</span>"
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-mode-dot-property-warning nil
+  "<span class="quote">If non-`nil', wan about expressions like $foo.bar, which could
+be a valid concatenation (if bar were a constant, or interpreted
+as an unquoted string), but it's more likely you meant $foo-&gt;bar.</span>"
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-mode-warn-on-unmatched nil
+  "<span class="quote">If non-`nil', use `font-lock-warning-face' on any expression
+that isn't matched by the other font lock regular expressions.</span>"
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-warn-if-mumamo-off t
+  "<span class="quote">Warn once per buffer if you try to indent a buffer without
+mumamo-mode turned on. Detects if there are any HTML tags in the
+buffer before warning, but this is not very smart; e.g. if you
+have any tags inside a PHP string, it will be fooled.</span>"
+  :type '(choice (const :tag "<span class="quote">Warn</span>" t) (const "<span class="quote">Don't warn</span>" nil))
+  :group 'php)
+
+
+(eval-when-compile
+  (defconst php-mode-modified
+    (save-excursion
+      (and
+       (re-search-backward "<span class="quote">^;; Modified: \\(.*\\)</span>" nil 'noerror)
+       (match-string-no-properties 1)))
+    "<span class="quote">PHP Mode version number.</span>"))
+
+(defun php-mode-version ()
+  "<span class="quote">Display string describing the version of PHP mode</span>"
+  (interactive)
+  (message "<span class="quote">PHP mode %s of %s</span>"
+           php-mode-version-number php-mode-modified))
+
+(defconst php-beginning-of-defun-regexp
+  "<span class="quote">^\\s *function\\s +&?\\(\\(\\sw\\|\\s_\\)+\\)\\s *(</span>"
+  "<span class="quote">Regular expression for a PHP function.</span>")
+
+(defun php-beginning-of-defun (&optional arg)
+  "<span class="quote">Move to the beginning of the ARGth PHP function from point.
+Implements PHP version of `beginning-of-defun-function'.</span>"
+  (interactive "<span class="quote">p</span>")
+  (let ((arg (or arg 1)))
+    (while (&gt; arg 0)
+      (re-search-backward php-beginning-of-defun-regexp
+                          nil 'noerror)
+      (setq arg (1- arg)))
+    (while (&lt; arg 0)
+      (end-of-line 1)
+      (let ((opoint (point)))
+        (beginning-of-defun 1)
+        (forward-list 2)
+        (forward-line 1)
+        (if (eq opoint (point))
+            (re-search-forward php-beginning-of-defun-regexp
+                               nil 'noerror))
+	(setq arg (1+ arg))))))
+
+(defun php-end-of-defun (&optional arg)
+  "<span class="quote">Move the end of the ARGth PHP function from point.
+Implements PHP befsion of `end-of-defun-function'
+
+See `php-beginning-of-defun'.</span>"
+  (interactive "<span class="quote">p</span>")
+  (php-beginning-of-defun (- (or arg 1))))
+
+
+(defvar php-completion-table nil
+  "<span class="quote">Obarray of tag names defined in current tags table and functions know to PHP.</span>")
+
+(defvar php-warned-bad-indent nil)
+<span class="linecomment">;;(make-variable-buffer-local 'php-warned-bad-indent)</span>
+
+<span class="linecomment">;; Do it but tell it is not good if html tags in buffer.</span>
+(defun php-check-html-for-indentation ()
+  (let ((html-tag-re "<span class="quote">&lt;/?\\sw+.*?&gt;</span>")
+        (here (point)))
+    (if (not (or (re-search-forward html-tag-re (+ (point) 1000) t)
+                 (re-search-backward html-tag-re (- (point) 1000) t)))
+        t
+      (goto-char here)
+      (setq php-warned-bad-indent t)
+      <span class="linecomment">;;(setq php-warned-bad-indent nil)</span>
+      (let* ((known-multi-libs '(("<span class="quote">mumamo</span>" mumamo (lambda () (nxhtml-mumamo)))
+                                 ("<span class="quote">mmm-mode</span>" mmm-mode (lambda () (mmm-mode 1)))
+                                 ("<span class="quote">multi-mode</span>" multi-mode (lambda () (multi-mode 1)))))
+             (known-names (mapcar (lambda (lib) (car lib)) known-multi-libs))
+             (available-multi-libs (delq nil
+                                         (mapcar
+                                          (lambda (lib)
+                                            (when (locate-library (car lib)) lib))
+                                          known-multi-libs)))
+             (available-names (mapcar (lambda (lib) (car lib)) available-multi-libs))
+             (base-msg
+              (concat
+               "<span class="quote">Indentation fails badly with mixed HTML/PHP in plaín\n</span>"
+               "<span class="quote">`php-mode'.  To get indentation to work you must use an Emacs\n</span>"
+               "<span class="quote">library that supports 'multiple major modes' in a buffer.  Parts\n</span>"
+               "<span class="quote">of the buffer will then be in `php-mode' and parts in for example\n</span>"
+               "<span class="quote">`html-mode'.  Known such libraries are:\n\t</span>"
+               (mapconcat 'identity known-names "<span class="quote">, </span>")
+               "<span class="quote">\n</span>"
+               (if available-multi-libs
+                   (concat
+                    "<span class="quote">You have these available in your `load-path':\n\t</span>"
+                    (mapconcat 'identity available-names "<span class="quote">, </span>")
+                    "<span class="quote">\n\n</span>"
+                    "<span class="quote">Do you want to turn any of those on? </span>")
+                 "<span class="quote">You do not have any of those in your `load-path'.</span>")))
+             (is-using-multi
+              (catch 'is-using
+                (dolist (lib available-multi-libs)
+                  (when (and (boundp (cadr lib))
+                             (symbol-value (cadr lib)))
+                    (throw 'is-using t))))))
+        (unless is-using-multi
+          (if available-multi-libs
+              (if (not (y-or-n-p base-msg))
+                  (message "<span class="quote">Did not do indentation, but you can try again now if you want</span>")
+                (let* ((name
+                        (if (= 1 (length available-multi-libs))
+                            (car available-names)
+                          <span class="linecomment">;; Minibuffer window is more than one line, fix that first:</span>
+                          (message "<span class="quote"></span>")
+                          (completing-read "<span class="quote">Choose multiple major mode support library: </span>"
+                                           available-names nil t
+                                           (car available-names)
+                                           '(available-names . 1)
+                                           )))
+                       (mode (when name
+                               (caddr (assoc name available-multi-libs)))))
+                  (when mode
+                    <span class="linecomment">;; Minibuffer window is more than one line, fix that first:</span>
+                    (message "<span class="quote"></span>")
+                    (load name)
+                    (funcall mode))))
+            (lwarn 'php-indent :warning base-msg)))
+        nil))))
+
+(defun php-cautious-indent-region (start end &optional quiet)
+  (if (or (not php-warn-if-mumamo-off)
+          php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (funcall 'c-indent-region start end quiet)))
+
+(defun php-cautious-indent-line ()
+  (if (or (not php-warn-if-mumamo-off)
+          php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (funcall 'c-indent-line)))
+
+<span class="linecomment">;;;###autoload</span>
+(define-derived-mode php-mode c-mode "<span class="quote">PHP</span>"
+  "<span class="quote">Major mode for editing PHP code.\n\n\\{php-mode-map}</span>"
+<span class="linecomment">;;   (c-add-language 'php-mode 'c-mode)</span>
+
+<span class="linecomment">;;   (c-lang-defconst c-block-stmt-1-kwds</span>
+<span class="linecomment">;;     php php-block-stmt-1-kwds)</span>
+  (set (make-local-variable 'c-block-stmt-1-key) php-block-stmt-1-key)
+
+<span class="linecomment">;;   (c-lang-defconst c-block-stmt-2-kwds</span>
+<span class="linecomment">;;     php php-block-stmt-2-kwds)</span>
+  (set (make-local-variable 'c-block-stmt-2-key) php-block-stmt-2-key)
+  <span class="linecomment">;; Specify that cc-mode recognize Javadoc comment style</span>
+  (set (make-local-variable 'c-doc-comment-style)
+    '((php-mode . javadoc)))
+
+<span class="linecomment">;;   (c-lang-defconst c-class-decl-kwds</span>
+<span class="linecomment">;;     php php-class-decl-kwds)</span>
+  (set (make-local-variable 'c-class-key) php-class-key)
+
+  <span class="linecomment">;; this line makes $ into punctuation instead of a word constituent</span>
+  <span class="linecomment">;; it used to be active, but it killed indenting of case lines that</span>
+  <span class="linecomment">;; begin with '$' (many do).  If anyone has a solution to this</span>
+  <span class="linecomment">;; problem, please let me know.  Of course, you're welcome to</span>
+  <span class="linecomment">;; uncomment this line in your installation.</span>
+<span class="linecomment">;  (modify-syntax-entry ?$ "." php-mode-syntax-table)</span>
+
+  <span class="linecomment">;; The above causes XEmacs to handle shell-style comments correctly,</span>
+  <span class="linecomment">;; but fails to work in GNU Emacs which fails to interpret \n as the</span>
+  <span class="linecomment">;; end of the comment.</span>
+  (if (featurep 'xemacs) (progn
+                (modify-syntax-entry ?# "<span class="quote">&lt; b</span>" php-mode-syntax-table)
+                (modify-syntax-entry ?\n "<span class="quote">&gt; b</span>" php-mode-syntax-table)))
+
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults
+        '((php-font-lock-keywords-1
+           php-font-lock-keywords-2
+               <span class="linecomment">;; Comment-out the next line if the font-coloring is too</span>
+               <span class="linecomment">;; extreme/ugly for you.</span>
+           php-font-lock-keywords-3)
+          nil                               <span class="linecomment">; KEYWORDS-ONLY</span>
+          nil                                 <span class="linecomment">; CASE-FOLD</span>
+          nil                               <span class="linecomment">; SYNTAX-ALIST</span>
+          nil))                             <span class="linecomment">; SYNTAX-BEGIN</span>
+  (modify-syntax-entry ?# "<span class="quote">&lt; b</span>" php-mode-syntax-table)
+  (modify-syntax-entry ?_ "<span class="quote">w</span>" php-mode-syntax-table)
+
+  <span class="linecomment">;; Electric behaviour must be turned off, they do not work since</span>
+  <span class="linecomment">;; they can not find the correct syntax in embedded PHP.</span>
+  <span class="linecomment">;;</span>
+  <span class="linecomment">;; Seems to work with narrowing so let it be on if the user prefers it.</span>
+  <span class="linecomment">;;(setq c-electric-flag nil)</span>
+
+  (setq font-lock-maximum-decoration t
+        case-fold-search t              <span class="linecomment">; PHP vars are case-sensitive</span>
+        imenu-generic-expression php-imenu-generic-expression)
+
+  <span class="linecomment">;; Do not force newline at end of file.  Such newlines can cause</span>
+  <span class="linecomment">;; trouble if the PHP file is included in another file before calls</span>
+  <span class="linecomment">;; to header() or cookie().</span>
+  (set (make-local-variable 'require-final-newline) nil)
+  (set (make-local-variable 'next-line-add-newlines) nil)
+
+  <span class="linecomment">;; PEAR coding standards</span>
+  (add-hook 'php-mode-pear-hook
+            (lambda ()
+              (set (make-local-variable 'tab-width) 4)
+              (set (make-local-variable 'c-basic-offset) 4)
+              (set (make-local-variable 'indent-tabs-mode) nil)
+              (c-set-offset 'block-open' - )
+              (c-set-offset 'block-close' 0 )) nil t)
+
+  (if (or php-mode-force-pear
+          (and (stringp buffer-file-name)
+               (string-match "<span class="quote">PEAR\\|pear</span>"
+                             (buffer-file-name))
+               (string-match "<span class="quote">\\.php$</span>" (buffer-file-name))))
+      (run-hooks 'php-mode-pear-hook))
+
+  (setq indent-line-function 'php-cautious-indent-line)
+  (setq indent-region-function 'php-cautious-indent-region)
+  (setq c-special-indent-hook nil)
+
+  (set (make-local-variable 'syntax-begin-function)
+       'c-beginning-of-syntax)
+  (set (make-local-variable 'beginning-of-defun-function)
+       'php-beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function)
+       'php-end-of-defun)
+  (set (make-local-variable 'open-paren-in-column-0-is-defun-start)
+       nil)
+  (set (make-local-variable 'defun-prompt-regexp)
+       "<span class="quote">^\\s *function\\s +&?\\(\\(\\sw\\|\\s_\\)+\\)\\s *</span>")
+  (set (make-local-variable 'add-log-current-defun-header-regexp)
+       php-beginning-of-defun-regexp)
+
+  (run-hooks 'php-mode-hook))
+
+<span class="linecomment">;; Make a menu keymap (with a prompt string)</span>
+<span class="linecomment">;; and make it the menu bar item's definition.</span>
+(define-key php-mode-map [menu-bar] (make-sparse-keymap))
+(define-key php-mode-map [menu-bar php]
+  (cons "<span class="quote">PHP</span>" (make-sparse-keymap "<span class="quote">PHP</span>")))
+
+<span class="linecomment">;; Define specific subcommands in this menu.</span>
+(define-key php-mode-map [menu-bar php complete-function]
+  '("<span class="quote">Complete function name</span>" . php-complete-function))
+(define-key php-mode-map
+  [menu-bar php browse-manual]
+  '("<span class="quote">Browse manual</span>" . php-browse-manual))
+(define-key php-mode-map
+  [menu-bar php search-documentation]
+  '("<span class="quote">Search documentation</span>" . php-search-documentation))
+
+<span class="linecomment">;; Define function name completion function</span>
+(defun php-complete-function ()
+  "<span class="quote">Perform function completion on the text around point.
+Completes to the set of names listed in the current tags table
+and the standard php functions.
+The string to complete is chosen in the same way as the default
+for \\[find-tag] (which see).</span>"
+  (interactive)
+  (let ((pattern (php-get-pattern))
+        beg
+        completion
+        (php-functions (php-completion-table)))
+    (if (not pattern) (message "<span class="quote">Nothing to complete</span>")
+        (search-backward pattern)
+        (setq beg (point))
+        (forward-char (length pattern))
+        (setq completion (try-completion pattern php-functions nil))
+        (cond ((eq completion t))
+              ((null completion)
+               (message "<span class="quote">Can't find completion for \"%s\"</span>" pattern)
+               (ding))
+              ((not (string= pattern completion))
+               (delete-region beg (point))
+               (insert completion))
+              (t
+               (message "<span class="quote">Making completion list...</span>")
+               (with-output-to-temp-buffer "<span class="quote">*Completions*</span>"
+                 (display-completion-list
+                  (all-completions pattern php-functions)))
+               (message "<span class="quote">Making completion list...%s</span>" "<span class="quote">done</span>"))))))
+
+<span class="linecomment">;; Build php-completion-table on demand.  The table includes the</span>
+<span class="linecomment">;; PHP functions and the tags from the current tags-file-name</span>
+(defun php-completion-table ()
+  (or (and tags-file-name
+           (save-excursion (tags-verify-table tags-file-name))
+           php-completion-table)
+      (let ((tags-table
+             (if (and tags-file-name
+                      (functionp 'etags-tags-completion-table))
+                 (with-current-buffer (get-file-buffer tags-file-name)
+                   (etags-tags-completion-table))
+               nil))
+            (php-table
+             (cond ((and (not (string= "<span class="quote"></span>" php-completion-file))
+                         (file-readable-p php-completion-file))
+                    (php-build-table-from-file php-completion-file))
+                   (php-manual-path
+                    (php-build-table-from-path php-manual-path))
+                   (t nil))))
+        (unless (or php-table tags-table)
+          (error
+           (concat "<span class="quote">No TAGS file active nor are </span>"
+                   "<span class="quote">`php-completion-file' or `php-manual-path' set</span>")))
+        (when tags-table
+          <span class="linecomment">;; Combine the tables.</span>
+          (mapatoms (lambda (sym) (intern (symbol-name sym) php-table))
+                    tags-table))
+        (setq php-completion-table php-table))))
+
+(defun php-build-table-from-file (filename)
+  (let ((table (make-vector 1022 0))
+        (buf (find-file-noselect filename)))
+    (save-excursion
+      (set-buffer buf)
+      (goto-char (point-min))
+      (while (re-search-forward
+              "<span class="quote">^\\([-a-zA-Z0-9_.]+\\)\n</span>"
+              nil t)
+        (intern (buffer-substring (match-beginning 1) (match-end 1))
+                table)))
+    (kill-buffer buf)
+    table))
+
+(defun php-build-table-from-path (path)
+  (let ((table (make-vector 1022 0))
+        (files (directory-files
+                path
+                nil
+                "<span class="quote">^function\\..+\\.html$</span>")))
+    (mapc (lambda (file)
+            (string-match "<span class="quote">\\.\\([-a-zA-Z_0-9]+\\)\\.html$</span>" file)
+            (intern
+             (replace-regexp-in-string
+              "<span class="quote">-</span>" "<span class="quote">_</span>" (substring file (match-beginning 1) (match-end 1)) t)
+             table))
+          files)
+    table))
+
+<span class="linecomment">;; Find the pattern we want to complete</span>
+<span class="linecomment">;; find-tag-default from GNU Emacs etags.el</span>
+(defun php-get-pattern ()
+  (save-excursion
+    (while (looking-at "<span class="quote">\\sw\\|\\s_</span>")
+      (forward-char 1))
+    (if (or (re-search-backward "<span class="quote">\\sw\\|\\s_</span>"
+                                (save-excursion (beginning-of-line) (point))
+                                t)
+            (re-search-forward "<span class="quote">\\(\\sw\\|\\s_\\)+</span>"
+                               (save-excursion (end-of-line) (point))
+                               t))
+        (progn (goto-char (match-end 0))
+               (buffer-substring-no-properties
+                (point)
+                (progn (forward-sexp -1)
+                       (while (looking-at "<span class="quote">\\s'</span>")
+                         (forward-char 1))
+                       (point))))
+      nil)))
+
+
+(defun php-show-arglist ()
+  (interactive)
+  (let* ((tagname (php-get-pattern)) arglist)
+    (save-excursion
+      (set-buffer (find-tag-noselect tagname nil nil))
+      (goto-char (point-min))
+      (when (re-search-forward
+             (format "<span class="quote">function[ \t]+%s[ \t]*(\\([^{]*\\))</span>" tagname)
+             nil t)
+        (setq arglist (buffer-substring-no-properties
+                       (match-beginning 1) (match-end 1)))))
+    (if arglist
+        (message "<span class="quote">Arglist for %s: %s</span>" tagname arglist)
+      (message "<span class="quote">Unknown function: %s</span>" tagname))))
+
+<span class="linecomment">;; Define function documentation function</span>
+(defun php-search-documentation ()
+  "<span class="quote">Search PHP documentation for the word at the point.</span>"
+  (interactive)
+  (browse-url (concat php-search-url (current-word t))))
+
+<span class="linecomment">;; Define function for browsing manual</span>
+(defun php-browse-manual ()
+  "<span class="quote">Bring up manual for PHP.</span>"
+  (interactive)
+  (browse-url php-manual-url))
+
+<span class="linecomment">;; Define shortcut</span>
+(define-key php-mode-map
+  "<span class="quote">\C-c\C-f</span>"
+  'php-search-documentation)
+
+<span class="linecomment">;; Define shortcut</span>
+(define-key php-mode-map
+  [(meta tab)]
+  'php-complete-function)
+
+<span class="linecomment">;; Define shortcut</span>
+(define-key php-mode-map
+  "<span class="quote">\C-c\C-m</span>"
+  'php-browse-manual)
+
+<span class="linecomment">;; Define shortcut</span>
+(define-key php-mode-map
+  '[(control .)]
+  'php-show-arglist)
+
+(defconst php-constants
+  (eval-when-compile
+    (regexp-opt
+     '(<span class="linecomment">;; core constants</span>
+       "<span class="quote">__LINE__</span>" "<span class="quote">__FILE__</span>"
+       "<span class="quote">__FUNCTION__</span>" "<span class="quote">__CLASS__</span>" "<span class="quote">__METHOD__</span>"
+       "<span class="quote">PHP_OS</span>" "<span class="quote">PHP_VERSION</span>"
+       "<span class="quote">TRUE</span>" "<span class="quote">FALSE</span>" "<span class="quote">NULL</span>"
+       "<span class="quote">E_ERROR</span>" "<span class="quote">E_NOTICE</span>" "<span class="quote">E_PARSE</span>" "<span class="quote">E_WARNING</span>" "<span class="quote">E_ALL</span>" "<span class="quote">E_STRICT</span>"
+       "<span class="quote">E_USER_ERROR</span>" "<span class="quote">E_USER_WARNING</span>" "<span class="quote">E_USER_NOTICE</span>"
+       "<span class="quote">DEFAULT_INCLUDE_PATH</span>" "<span class="quote">PEAR_INSTALL_DIR</span>" "<span class="quote">PEAR_EXTENSION_DIR</span>"
+       "<span class="quote">PHP_BINDIR</span>" "<span class="quote">PHP_LIBDIR</span>" "<span class="quote">PHP_DATADIR</span>" "<span class="quote">PHP_SYSCONFDIR</span>"
+       "<span class="quote">PHP_LOCALSTATEDIR</span>" "<span class="quote">PHP_CONFIG_FILE_PATH</span>"
+       "<span class="quote">PHP_EOL</span>"
+
+       <span class="linecomment">;; from ext/standard:</span>
+       "<span class="quote">EXTR_OVERWRITE</span>" "<span class="quote">EXTR_SKIP</span>" "<span class="quote">EXTR_PREFIX_SAME</span>"
+       "<span class="quote">EXTR_PREFIX_ALL</span>" "<span class="quote">EXTR_PREFIX_INVALID</span>" "<span class="quote">SORT_ASC</span>" "<span class="quote">SORT_DESC</span>"
+       "<span class="quote">SORT_REGULAR</span>" "<span class="quote">SORT_NUMERIC</span>" "<span class="quote">SORT_STRING</span>" "<span class="quote">ASSERT_ACTIVE</span>"
+       "<span class="quote">ASSERT_CALLBACK</span>" "<span class="quote">ASSERT_BAIL</span>" "<span class="quote">ASSERT_WARNING</span>"
+       "<span class="quote">ASSERT_QUIET_EVAL</span>" "<span class="quote">CONNECTION_ABORTED</span>" "<span class="quote">CONNECTION_NORMAL</span>"
+       "<span class="quote">CONNECTION_TIMEOUT</span>" "<span class="quote">M_E</span>" "<span class="quote">M_LOG2E</span>" "<span class="quote">M_LOG10E</span>" "<span class="quote">M_LN2</span>"
+       "<span class="quote">M_LN10</span>" "<span class="quote">M_PI</span>" "<span class="quote">M_PI_2</span>" "<span class="quote">M_PI_4</span>" "<span class="quote">M_1_PI</span>" "<span class="quote">M_2_PI</span>"
+       "<span class="quote">M_2_SQRTPI</span>" "<span class="quote">M_SQRT2</span>" "<span class="quote">M_SQRT1_2</span>" "<span class="quote">CRYPT_SALT_LENGTH</span>"
+       "<span class="quote">CRYPT_STD_DES</span>" "<span class="quote">CRYPT_EXT_DES</span>" "<span class="quote">CRYPT_MD5</span>" "<span class="quote">CRYPT_BLOWFISH</span>"
+       "<span class="quote">DIRECTORY_SEPARATOR</span>" "<span class="quote">SEEK_SET</span>" "<span class="quote">SEEK_CUR</span>" "<span class="quote">SEEK_END</span>"
+       "<span class="quote">LOCK_SH</span>" "<span class="quote">LOCK_EX</span>" "<span class="quote">LOCK_UN</span>" "<span class="quote">LOCK_NB</span>" "<span class="quote">HTML_SPECIALCHARS</span>"
+       "<span class="quote">HTML_ENTITIES</span>" "<span class="quote">ENT_COMPAT</span>" "<span class="quote">ENT_QUOTES</span>" "<span class="quote">ENT_NOQUOTES</span>"
+       "<span class="quote">INFO_GENERAL</span>" "<span class="quote">INFO_CREDITS</span>" "<span class="quote">INFO_CONFIGURATION</span>"
+       "<span class="quote">INFO_ENVIRONMENT</span>" "<span class="quote">INFO_VARIABLES</span>" "<span class="quote">INFO_LICENSE</span>" "<span class="quote">INFO_ALL</span>"
+       "<span class="quote">CREDITS_GROUP</span>" "<span class="quote">CREDITS_GENERAL</span>" "<span class="quote">CREDITS_SAPI</span>"
+       "<span class="quote">CREDITS_MODULES</span>" "<span class="quote">CREDITS_DOCS</span>" "<span class="quote">CREDITS_FULLPAGE</span>"
+       "<span class="quote">CREDITS_QA</span>" "<span class="quote">CREDITS_ALL</span>" "<span class="quote">PHP_OUTPUT_HANDLER_START</span>"
+       "<span class="quote">PHP_OUTPUT_HANDLER_CONT</span>" "<span class="quote">PHP_OUTPUT_HANDLER_END</span>"
+       "<span class="quote">STR_PAD_LEFT</span>" "<span class="quote">STR_PAD_RIGHT</span>" "<span class="quote">STR_PAD_BOTH</span>"
+       "<span class="quote">PATHINFO_DIRNAME</span>" "<span class="quote">PATHINFO_BASENAME</span>" "<span class="quote">PATHINFO_EXTENSION</span>"
+       "<span class="quote">CHAR_MAX</span>" "<span class="quote">LC_CTYPE</span>" "<span class="quote">LC_NUMERIC</span>" "<span class="quote">LC_TIME</span>" "<span class="quote">LC_COLLATE</span>"
+       "<span class="quote">LC_MONETARY</span>" "<span class="quote">LC_ALL</span>" "<span class="quote">LC_MESSAGES</span>" "<span class="quote">LOG_EMERG</span>" "<span class="quote">LOG_ALERT</span>"
+       "<span class="quote">LOG_CRIT</span>" "<span class="quote">LOG_ERR</span>" "<span class="quote">LOG_WARNING</span>" "<span class="quote">LOG_NOTICE</span>" "<span class="quote">LOG_INFO</span>"
+       "<span class="quote">LOG_DEBUG</span>" "<span class="quote">LOG_KERN</span>" "<span class="quote">LOG_USER</span>" "<span class="quote">LOG_MAIL</span>" "<span class="quote">LOG_DAEMON</span>"
+       "<span class="quote">LOG_AUTH</span>" "<span class="quote">LOG_SYSLOG</span>" "<span class="quote">LOG_LPR</span>" "<span class="quote">LOG_NEWS</span>" "<span class="quote">LOG_UUCP</span>"
+       "<span class="quote">LOG_CRON</span>" "<span class="quote">LOG_AUTHPRIV</span>" "<span class="quote">LOG_LOCAL0</span>" "<span class="quote">LOG_LOCAL1</span>"
+       "<span class="quote">LOG_LOCAL2</span>" "<span class="quote">LOG_LOCAL3</span>" "<span class="quote">LOG_LOCAL4</span>" "<span class="quote">LOG_LOCAL5</span>"
+       "<span class="quote">LOG_LOCAL6</span>" "<span class="quote">LOG_LOCAL7</span>" "<span class="quote">LOG_PID</span>" "<span class="quote">LOG_CONS</span>" "<span class="quote">LOG_ODELAY</span>"
+       "<span class="quote">LOG_NDELAY</span>" "<span class="quote">LOG_NOWAIT</span>" "<span class="quote">LOG_PERROR</span>"
+
+       <span class="linecomment">;; Disabled by default because they slow buffer loading</span>
+       <span class="linecomment">;; If you have use for them, uncomment the strings</span>
+       <span class="linecomment">;; that you want colored.</span>
+       <span class="linecomment">;; To compile, you may have to increase 'max-specpdl-size'</span>
+
+       <span class="linecomment">;; from other bundled extensions:</span>
+<span class="linecomment">;        "CAL_EASTER_TO_xxx" "VT_NULL" "VT_EMPTY" "VT_UI1" "VT_I2"</span>
+<span class="linecomment">;        "VT_I4" "VT_R4" "VT_R8" "VT_BOOL" "VT_ERROR" "VT_CY" "VT_DATE"</span>
+<span class="linecomment">;        "VT_BSTR" "VT_DECIMAL" "VT_UNKNOWN" "VT_DISPATCH" "VT_VARIANT"</span>
+<span class="linecomment">;        "VT_I1" "VT_UI2" "VT_UI4" "VT_INT" "VT_UINT" "VT_ARRAY"</span>
+<span class="linecomment">;        "VT_BYREF" "CP_ACP" "CP_MACCP" "CP_OEMCP" "CP_SYMBOL"</span>
+<span class="linecomment">;        "CP_THREAD_ACP" "CP_UTF7" "CP_UTF8" "CPDF_PM_NONE"</span>
+<span class="linecomment">;        "CPDF_PM_OUTLINES" "CPDF_PM_THUMBS" "CPDF_PM_FULLSCREEN"</span>
+<span class="linecomment">;        "CPDF_PL_SINGLE" "CPDF_PL_1COLUMN" "CPDF_PL_2LCOLUMN"</span>
+<span class="linecomment">;        "CPDF_PL_2RCOLUMN" "CURLOPT_PORT" "CURLOPT_FILE"</span>
+<span class="linecomment">;        "CURLOPT_INFILE" "CURLOPT_INFILESIZE" "CURLOPT_URL"</span>
+<span class="linecomment">;        "CURLOPT_PROXY" "CURLOPT_VERBOSE" "CURLOPT_HEADER"</span>
+<span class="linecomment">;        "CURLOPT_HTTPHEADER" "CURLOPT_NOPROGRESS" "CURLOPT_NOBODY"</span>
+<span class="linecomment">;        "CURLOPT_FAILONERROR" "CURLOPT_UPLOAD" "CURLOPT_POST"</span>
+<span class="linecomment">;        "CURLOPT_FTPLISTONLY" "CURLOPT_FTPAPPEND" "CURLOPT_NETRC"</span>
+<span class="linecomment">;        "CURLOPT_FOLLOWLOCATION" "CURLOPT_FTPASCII" "CURLOPT_PUT"</span>
+<span class="linecomment">;        "CURLOPT_MUTE" "CURLOPT_USERPWD" "CURLOPT_PROXYUSERPWD"</span>
+<span class="linecomment">;        "CURLOPT_RANGE" "CURLOPT_TIMEOUT" "CURLOPT_POSTFIELDS"</span>
+<span class="linecomment">;        "CURLOPT_REFERER" "CURLOPT_USERAGENT" "CURLOPT_FTPPORT"</span>
+<span class="linecomment">;        "CURLOPT_LOW_SPEED_LIMIT" "CURLOPT_LOW_SPEED_TIME"</span>
+<span class="linecomment">;        "CURLOPT_RESUME_FROM" "CURLOPT_COOKIE" "CURLOPT_SSLCERT"</span>
+<span class="linecomment">;        "CURLOPT_SSLCERTPASSWD" "CURLOPT_WRITEHEADER"</span>
+<span class="linecomment">;        "CURLOPT_COOKIEFILE" "CURLOPT_SSLVERSION"</span>
+<span class="linecomment">;        "CURLOPT_TIMECONDITION" "CURLOPT_TIMEVALUE"</span>
+<span class="linecomment">;        "CURLOPT_CUSTOMREQUEST" "CURLOPT_STDERR" "CURLOPT_TRANSFERTEXT"</span>
+<span class="linecomment">;        "CURLOPT_RETURNTRANSFER" "CURLOPT_QUOTE" "CURLOPT_POSTQUOTE"</span>
+<span class="linecomment">;        "CURLOPT_INTERFACE" "CURLOPT_KRB4LEVEL"</span>
+<span class="linecomment">;        "CURLOPT_HTTPPROXYTUNNEL" "CURLOPT_FILETIME"</span>
+<span class="linecomment">;        "CURLOPT_WRITEFUNCTION" "CURLOPT_READFUNCTION"</span>
+<span class="linecomment">;        "CURLOPT_PASSWDFUNCTION" "CURLOPT_HEADERFUNCTION"</span>
+<span class="linecomment">;        "CURLOPT_MAXREDIRS" "CURLOPT_MAXCONNECTS" "CURLOPT_CLOSEPOLICY"</span>
+<span class="linecomment">;        "CURLOPT_FRESH_CONNECT" "CURLOPT_FORBID_REUSE"</span>
+<span class="linecomment">;        "CURLOPT_RANDOM_FILE" "CURLOPT_EGDSOCKET"</span>
+<span class="linecomment">;        "CURLOPT_CONNECTTIMEOUT" "CURLOPT_SSL_VERIFYPEER"</span>
+<span class="linecomment">;        "CURLOPT_CAINFO" "CURLOPT_BINARYTRANSER"</span>
+<span class="linecomment">;        "CURLCLOSEPOLICY_LEAST_RECENTLY_USED" "CURLCLOSEPOLICY_OLDEST"</span>
+<span class="linecomment">;        "CURLINFO_EFFECTIVE_URL" "CURLINFO_HTTP_CODE"</span>
+<span class="linecomment">;        "CURLINFO_HEADER_SIZE" "CURLINFO_REQUEST_SIZE"</span>
+<span class="linecomment">;        "CURLINFO_TOTAL_TIME" "CURLINFO_NAMELOOKUP_TIME"</span>
+<span class="linecomment">;        "CURLINFO_CONNECT_TIME" "CURLINFO_PRETRANSFER_TIME"</span>
+<span class="linecomment">;        "CURLINFO_SIZE_UPLOAD" "CURLINFO_SIZE_DOWNLOAD"</span>
+<span class="linecomment">;        "CURLINFO_SPEED_DOWNLOAD" "CURLINFO_SPEED_UPLOAD"</span>
+<span class="linecomment">;        "CURLINFO_FILETIME" "CURLE_OK" "CURLE_UNSUPPORTED_PROTOCOL"</span>
+<span class="linecomment">;        "CURLE_FAILED_INIT" "CURLE_URL_MALFORMAT"</span>
+<span class="linecomment">;        "CURLE_URL_MALFORMAT_USER" "CURLE_COULDNT_RESOLVE_PROXY"</span>
+<span class="linecomment">;        "CURLE_COULDNT_RESOLVE_HOST" "CURLE_COULDNT_CONNECT"</span>
+<span class="linecomment">;        "CURLE_FTP_WEIRD_SERVER_REPLY" "CURLE_FTP_ACCESS_DENIED"</span>
+<span class="linecomment">;        "CURLE_FTP_USER_PASSWORD_INCORRECT"</span>
+<span class="linecomment">;        "CURLE_FTP_WEIRD_PASS_REPLY" "CURLE_FTP_WEIRD_USER_REPLY"</span>
+<span class="linecomment">;        "CURLE_FTP_WEIRD_PASV_REPLY" "CURLE_FTP_WEIRD_227_FORMAT"</span>
+<span class="linecomment">;        "CURLE_FTP_CANT_GET_HOST" "CURLE_FTP_CANT_RECONNECT"</span>
+<span class="linecomment">;        "CURLE_FTP_COULDNT_SET_BINARY" "CURLE_PARTIAL_FILE"</span>
+<span class="linecomment">;        "CURLE_FTP_COULDNT_RETR_FILE" "CURLE_FTP_WRITE_ERROR"</span>
+<span class="linecomment">;        "CURLE_FTP_QUOTE_ERROR" "CURLE_HTTP_NOT_FOUND"</span>
+<span class="linecomment">;        "CURLE_WRITE_ERROR" "CURLE_MALFORMAT_USER"</span>
+<span class="linecomment">;        "CURLE_FTP_COULDNT_STOR_FILE" "CURLE_READ_ERROR"</span>
+<span class="linecomment">;        "CURLE_OUT_OF_MEMORY" "CURLE_OPERATION_TIMEOUTED"</span>
+<span class="linecomment">;        "CURLE_FTP_COULDNT_SET_ASCII" "CURLE_FTP_PORT_FAILED"</span>
+<span class="linecomment">;        "CURLE_FTP_COULDNT_USE_REST" "CURLE_FTP_COULDNT_GET_SIZE"</span>
+<span class="linecomment">;        "CURLE_HTTP_RANGE_ERROR" "CURLE_HTTP_POST_ERROR"</span>
+<span class="linecomment">;        "CURLE_SSL_CONNECT_ERROR" "CURLE_FTP_BAD_DOWNLOAD_RESUME"</span>
+<span class="linecomment">;        "CURLE_FILE_COULDNT_READ_FILE" "CURLE_LDAP_CANNOT_BIND"</span>
+<span class="linecomment">;        "CURLE_LDAP_SEARCH_FAILED" "CURLE_LIBRARY_NOT_FOUND"</span>
+<span class="linecomment">;        "CURLE_FUNCTION_NOT_FOUND" "CURLE_ABORTED_BY_CALLBACK"</span>
+<span class="linecomment">;        "CURLE_BAD_FUNCTION_ARGUMENT" "CURLE_BAD_CALLING_ORDER"</span>
+<span class="linecomment">;        "CURLE_HTTP_PORT_FAILED" "CURLE_BAD_PASSWORD_ENTERED"</span>
+<span class="linecomment">;        "CURLE_TOO_MANY_REDIRECTS" "CURLE_UNKOWN_TELNET_OPTION"</span>
+<span class="linecomment">;        "CURLE_TELNET_OPTION_SYNTAX" "CURLE_ALREADY_COMPLETE"</span>
+<span class="linecomment">;        "DBX_MYSQL" "DBX_ODBC" "DBX_PGSQL" "DBX_MSSQL" "DBX_PERSISTENT"</span>
+<span class="linecomment">;        "DBX_RESULT_INFO" "DBX_RESULT_INDEX" "DBX_RESULT_ASSOC"</span>
+<span class="linecomment">;        "DBX_CMP_TEXT" "DBX_CMP_NUMBER" "XML_ELEMENT_NODE"</span>
+<span class="linecomment">;        "XML_ATTRIBUTE_NODE" "XML_TEXT_NODE" "XML_CDATA_SECTION_NODE"</span>
+<span class="linecomment">;        "XML_ENTITY_REF_NODE" "XML_ENTITY_NODE" "XML_PI_NODE"</span>
+<span class="linecomment">;        "XML_COMMENT_NODE" "XML_DOCUMENT_NODE" "XML_DOCUMENT_TYPE_NODE"</span>
+<span class="linecomment">;        "XML_DOCUMENT_FRAG_NODE" "XML_NOTATION_NODE"</span>
+<span class="linecomment">;        "XML_HTML_DOCUMENT_NODE" "XML_DTD_NODE" "XML_ELEMENT_DECL_NODE"</span>
+<span class="linecomment">;        "XML_ATTRIBUTE_DECL_NODE" "XML_ENTITY_DECL_NODE"</span>
+<span class="linecomment">;        "XML_NAMESPACE_DECL_NODE" "XML_GLOBAL_NAMESPACE"</span>
+<span class="linecomment">;        "XML_LOCAL_NAMESPACE" "XML_ATTRIBUTE_CDATA" "XML_ATTRIBUTE_ID"</span>
+<span class="linecomment">;        "XML_ATTRIBUTE_IDREF" "XML_ATTRIBUTE_IDREFS"</span>
+<span class="linecomment">;        "XML_ATTRIBUTE_ENTITY" "XML_ATTRIBUTE_NMTOKEN"</span>
+<span class="linecomment">;        "XML_ATTRIBUTE_NMTOKENS" "XML_ATTRIBUTE_ENUMERATION"</span>
+<span class="linecomment">;        "XML_ATTRIBUTE_NOTATION" "XPATH_UNDEFINED" "XPATH_NODESET"</span>
+<span class="linecomment">;        "XPATH_BOOLEAN" "XPATH_NUMBER" "XPATH_STRING" "XPATH_POINT"</span>
+<span class="linecomment">;        "XPATH_RANGE" "XPATH_LOCATIONSET" "XPATH_USERS" "FBSQL_ASSOC"</span>
+<span class="linecomment">;        "FBSQL_NUM" "FBSQL_BOTH" "FDFValue" "FDFStatus" "FDFFile"</span>
+<span class="linecomment">;        "FDFID" "FDFFf" "FDFSetFf" "FDFClearFf" "FDFFlags" "FDFSetF"</span>
+<span class="linecomment">;        "FDFClrF" "FDFAP" "FDFAS" "FDFAction" "FDFAA" "FDFAPRef"</span>
+<span class="linecomment">;        "FDFIF" "FDFEnter" "FDFExit" "FDFDown" "FDFUp" "FDFFormat"</span>
+<span class="linecomment">;        "FDFValidate" "FDFKeystroke" "FDFCalculate"</span>
+<span class="linecomment">;        "FRIBIDI_CHARSET_UTF8" "FRIBIDI_CHARSET_8859_6"</span>
+<span class="linecomment">;        "FRIBIDI_CHARSET_8859_8" "FRIBIDI_CHARSET_CP1255"</span>
+<span class="linecomment">;        "FRIBIDI_CHARSET_CP1256" "FRIBIDI_CHARSET_ISIRI_3342"</span>
+<span class="linecomment">;        "FTP_ASCII" "FTP_BINARY" "FTP_IMAGE" "FTP_TEXT" "IMG_GIF"</span>
+<span class="linecomment">;        "IMG_JPG" "IMG_JPEG" "IMG_PNG" "IMG_WBMP" "IMG_COLOR_TILED"</span>
+<span class="linecomment">;        "IMG_COLOR_STYLED" "IMG_COLOR_BRUSHED"</span>
+<span class="linecomment">;        "IMG_COLOR_STYLEDBRUSHED" "IMG_COLOR_TRANSPARENT"</span>
+<span class="linecomment">;        "IMG_ARC_ROUNDED" "IMG_ARC_PIE" "IMG_ARC_CHORD"</span>
+<span class="linecomment">;        "IMG_ARC_NOFILL" "IMG_ARC_EDGED" "GMP_ROUND_ZERO"</span>
+<span class="linecomment">;        "GMP_ROUND_PLUSINF" "GMP_ROUND_MINUSINF" "HW_ATTR_LANG"</span>
+<span class="linecomment">;        "HW_ATTR_NR" "HW_ATTR_NONE" "IIS_READ" "IIS_WRITE"</span>
+<span class="linecomment">;        "IIS_EXECUTE" "IIS_SCRIPT" "IIS_ANONYMOUS" "IIS_BASIC"</span>
+<span class="linecomment">;        "IIS_NTLM" "NIL" "OP_DEBUG" "OP_READONLY" "OP_ANONYMOUS"</span>
+<span class="linecomment">;        "OP_SHORTCACHE" "OP_SILENT" "OP_PROTOTYPE" "OP_HALFOPEN"</span>
+<span class="linecomment">;        "OP_EXPUNGE" "OP_SECURE" "CL_EXPUNGE" "FT_UID" "FT_PEEK"</span>
+<span class="linecomment">;        "FT_NOT" "FT_INTERNAL" "FT_PREFETCHTEXT" "ST_UID" "ST_SILENT"</span>
+<span class="linecomment">;        "ST_SET" "CP_UID" "CP_MOVE" "SE_UID" "SE_FREE" "SE_NOPREFETCH"</span>
+<span class="linecomment">;        "SO_FREE" "SO_NOSERVER" "SA_MESSAGES" "SA_RECENT" "SA_UNSEEN"</span>
+<span class="linecomment">;        "SA_UIDNEXT" "SA_UIDVALIDITY" "SA_ALL" "LATT_NOINFERIORS"</span>
+<span class="linecomment">;        "LATT_NOSELECT" "LATT_MARKED" "LATT_UNMARKED" "SORTDATE"</span>
+<span class="linecomment">;        "SORTARRIVAL" "SORTFROM" "SORTSUBJECT" "SORTTO" "SORTCC"</span>
+<span class="linecomment">;        "SORTSIZE" "TYPETEXT" "TYPEMULTIPART" "TYPEMESSAGE"</span>
+<span class="linecomment">;        "TYPEAPPLICATION" "TYPEAUDIO" "TYPEIMAGE" "TYPEVIDEO"</span>
+<span class="linecomment">;        "TYPEOTHER" "ENC7BIT" "ENC8BIT" "ENCBINARY" "ENCBASE64"</span>
+<span class="linecomment">;        "ENCQUOTEDPRINTABLE" "ENCOTHER" "INGRES_ASSOC" "INGRES_NUM"</span>
+<span class="linecomment">;        "INGRES_BOTH" "IBASE_DEFAULT" "IBASE_TEXT" "IBASE_UNIXTIME"</span>
+<span class="linecomment">;        "IBASE_READ" "IBASE_COMMITTED" "IBASE_CONSISTENCY"</span>
+<span class="linecomment">;        "IBASE_NOWAIT" "IBASE_TIMESTAMP" "IBASE_DATE" "IBASE_TIME"</span>
+<span class="linecomment">;        "LDAP_DEREF_NEVER" "LDAP_DEREF_SEARCHING" "LDAP_DEREF_FINDING"</span>
+<span class="linecomment">;        "LDAP_DEREF_ALWAYS" "LDAP_OPT_DEREF" "LDAP_OPT_SIZELIMIT"</span>
+<span class="linecomment">;        "LDAP_OPT_TIMELIMIT" "LDAP_OPT_PROTOCOL_VERSION"</span>
+<span class="linecomment">;        "LDAP_OPT_ERROR_NUMBER" "LDAP_OPT_REFERRALS" "LDAP_OPT_RESTART"</span>
+<span class="linecomment">;        "LDAP_OPT_HOST_NAME" "LDAP_OPT_ERROR_STRING"</span>
+<span class="linecomment">;        "LDAP_OPT_MATCHED_DN" "LDAP_OPT_SERVER_CONTROLS"</span>
+<span class="linecomment">;        "LDAP_OPT_CLIENT_CONTROLS" "GSLC_SSL_NO_AUTH"</span>
+<span class="linecomment">;        "GSLC_SSL_ONEWAY_AUTH" "GSLC_SSL_TWOWAY_AUTH" "MCAL_SUNDAY"</span>
+<span class="linecomment">;        "MCAL_MONDAY" "MCAL_TUESDAY" "MCAL_WEDNESDAY" "MCAL_THURSDAY"</span>
+<span class="linecomment">;        "MCAL_FRIDAY" "MCAL_SATURDAY" "MCAL_JANUARY" "MCAL_FEBRUARY"</span>
+<span class="linecomment">;        "MCAL_MARCH" "MCAL_APRIL" "MCAL_MAY" "MCAL_JUNE" "MCAL_JULY"</span>
+<span class="linecomment">;        "MCAL_AUGUST" "MCAL_SEPTEMBER" "MCAL_OCTOBER" "MCAL_NOVEMBER"</span>
+<span class="linecomment">;        "MCAL_RECUR_NONE" "MCAL_RECUR_DAILY" "MCAL_RECUR_WEEKLY"</span>
+<span class="linecomment">;        "MCAL_RECUR_MONTHLY_MDAY" "MCAL_RECUR_MONTHLY_WDAY"</span>
+<span class="linecomment">;        "MCAL_RECUR_YEARLY" "MCAL_M_SUNDAY" "MCAL_M_MONDAY"</span>
+<span class="linecomment">;        "MCAL_M_TUESDAY" "MCAL_M_WEDNESDAY" "MCAL_M_THURSDAY"</span>
+<span class="linecomment">;        "MCAL_M_FRIDAY" "MCAL_M_SATURDAY" "MCAL_M_WEEKDAYS"</span>
+<span class="linecomment">;        "MCAL_M_WEEKEND" "MCAL_M_ALLDAYS" "MCRYPT_" "MCRYPT_"</span>
+<span class="linecomment">;        "MCRYPT_ENCRYPT" "MCRYPT_DECRYPT" "MCRYPT_DEV_RANDOM"</span>
+<span class="linecomment">;        "MCRYPT_DEV_URANDOM" "MCRYPT_RAND" "SWFBUTTON_HIT"</span>
+<span class="linecomment">;        "SWFBUTTON_DOWN" "SWFBUTTON_OVER" "SWFBUTTON_UP"</span>
+<span class="linecomment">;        "SWFBUTTON_MOUSEUPOUTSIDE" "SWFBUTTON_DRAGOVER"</span>
+<span class="linecomment">;        "SWFBUTTON_DRAGOUT" "SWFBUTTON_MOUSEUP" "SWFBUTTON_MOUSEDOWN"</span>
+<span class="linecomment">;        "SWFBUTTON_MOUSEOUT" "SWFBUTTON_MOUSEOVER"</span>
+<span class="linecomment">;        "SWFFILL_RADIAL_GRADIENT" "SWFFILL_LINEAR_GRADIENT"</span>
+<span class="linecomment">;        "SWFFILL_TILED_BITMAP" "SWFFILL_CLIPPED_BITMAP"</span>
+<span class="linecomment">;        "SWFTEXTFIELD_HASLENGTH" "SWFTEXTFIELD_NOEDIT"</span>
+<span class="linecomment">;        "SWFTEXTFIELD_PASSWORD" "SWFTEXTFIELD_MULTILINE"</span>
+<span class="linecomment">;        "SWFTEXTFIELD_WORDWRAP" "SWFTEXTFIELD_DRAWBOX"</span>
+<span class="linecomment">;        "SWFTEXTFIELD_NOSELECT" "SWFTEXTFIELD_HTML"</span>
+<span class="linecomment">;        "SWFTEXTFIELD_ALIGN_LEFT" "SWFTEXTFIELD_ALIGN_RIGHT"</span>
+<span class="linecomment">;        "SWFTEXTFIELD_ALIGN_CENTER" "SWFTEXTFIELD_ALIGN_JUSTIFY"</span>
+<span class="linecomment">;        "UDM_FIELD_URLID" "UDM_FIELD_URL" "UDM_FIELD_CONTENT"</span>
+<span class="linecomment">;        "UDM_FIELD_TITLE" "UDM_FIELD_KEYWORDS" "UDM_FIELD_DESC"</span>
+<span class="linecomment">;        "UDM_FIELD_DESCRIPTION" "UDM_FIELD_TEXT" "UDM_FIELD_SIZE"</span>
+<span class="linecomment">;        "UDM_FIELD_RATING" "UDM_FIELD_SCORE" "UDM_FIELD_MODIFIED"</span>
+<span class="linecomment">;        "UDM_FIELD_ORDER" "UDM_FIELD_CRC" "UDM_FIELD_CATEGORY"</span>
+<span class="linecomment">;        "UDM_PARAM_PAGE_SIZE" "UDM_PARAM_PAGE_NUM"</span>
+<span class="linecomment">;        "UDM_PARAM_SEARCH_MODE" "UDM_PARAM_CACHE_MODE"</span>
+<span class="linecomment">;        "UDM_PARAM_TRACK_MODE" "UDM_PARAM_PHRASE_MODE"</span>
+<span class="linecomment">;        "UDM_PARAM_CHARSET" "UDM_PARAM_STOPTABLE"</span>
+<span class="linecomment">;        "UDM_PARAM_STOP_TABLE" "UDM_PARAM_STOPFILE"</span>
+<span class="linecomment">;        "UDM_PARAM_STOP_FILE" "UDM_PARAM_WEIGHT_FACTOR"</span>
+<span class="linecomment">;        "UDM_PARAM_WORD_MATCH" "UDM_PARAM_MAX_WORD_LEN"</span>
+<span class="linecomment">;        "UDM_PARAM_MAX_WORDLEN" "UDM_PARAM_MIN_WORD_LEN"</span>
+<span class="linecomment">;        "UDM_PARAM_MIN_WORDLEN" "UDM_PARAM_ISPELL_PREFIXES"</span>
+<span class="linecomment">;        "UDM_PARAM_ISPELL_PREFIX" "UDM_PARAM_PREFIXES"</span>
+<span class="linecomment">;        "UDM_PARAM_PREFIX" "UDM_PARAM_CROSS_WORDS"</span>
+<span class="linecomment">;        "UDM_PARAM_CROSSWORDS" "UDM_LIMIT_CAT" "UDM_LIMIT_URL"</span>
+<span class="linecomment">;        "UDM_LIMIT_TAG" "UDM_LIMIT_LANG" "UDM_LIMIT_DATE"</span>
+<span class="linecomment">;        "UDM_PARAM_FOUND" "UDM_PARAM_NUM_ROWS" "UDM_PARAM_WORDINFO"</span>
+<span class="linecomment">;        "UDM_PARAM_WORD_INFO" "UDM_PARAM_SEARCHTIME"</span>
+<span class="linecomment">;        "UDM_PARAM_SEARCH_TIME" "UDM_PARAM_FIRST_DOC"</span>
+<span class="linecomment">;        "UDM_PARAM_LAST_DOC" "UDM_MODE_ALL" "UDM_MODE_ANY"</span>
+<span class="linecomment">;        "UDM_MODE_BOOL" "UDM_MODE_PHRASE" "UDM_CACHE_ENABLED"</span>
+<span class="linecomment">;        "UDM_CACHE_DISABLED" "UDM_TRACK_ENABLED" "UDM_TRACK_DISABLED"</span>
+<span class="linecomment">;        "UDM_PHRASE_ENABLED" "UDM_PHRASE_DISABLED"</span>
+<span class="linecomment">;        "UDM_CROSS_WORDS_ENABLED" "UDM_CROSSWORDS_ENABLED"</span>
+<span class="linecomment">;        "UDM_CROSS_WORDS_DISABLED" "UDM_CROSSWORDS_DISABLED"</span>
+<span class="linecomment">;        "UDM_PREFIXES_ENABLED" "UDM_PREFIX_ENABLED"</span>
+<span class="linecomment">;        "UDM_ISPELL_PREFIXES_ENABLED" "UDM_ISPELL_PREFIX_ENABLED"</span>
+<span class="linecomment">;        "UDM_PREFIXES_DISABLED" "UDM_PREFIX_DISABLED"</span>
+<span class="linecomment">;        "UDM_ISPELL_PREFIXES_DISABLED" "UDM_ISPELL_PREFIX_DISABLED"</span>
+<span class="linecomment">;        "UDM_ISPELL_TYPE_AFFIX" "UDM_ISPELL_TYPE_SPELL"</span>
+<span class="linecomment">;        "UDM_ISPELL_TYPE_DB" "UDM_ISPELL_TYPE_SERVER" "UDM_MATCH_WORD"</span>
+<span class="linecomment">;        "UDM_MATCH_BEGIN" "UDM_MATCH_SUBSTR" "UDM_MATCH_END"</span>
+<span class="linecomment">;        "MSQL_ASSOC" "MSQL_NUM" "MSQL_BOTH" "MYSQL_ASSOC" "MYSQL_NUM"</span>
+<span class="linecomment">;        "MYSQL_BOTH" "MYSQL_USE_RESULT" "MYSQL_STORE_RESULT"</span>
+<span class="linecomment">;        "OCI_DEFAULT" "OCI_DESCRIBE_ONLY" "OCI_COMMIT_ON_SUCCESS"</span>
+<span class="linecomment">;        "OCI_EXACT_FETCH" "SQLT_BFILEE" "SQLT_CFILEE" "SQLT_CLOB"</span>
+<span class="linecomment">;        "SQLT_BLOB" "SQLT_RDD" "OCI_B_SQLT_NTY" "OCI_SYSDATE"</span>
+<span class="linecomment">;        "OCI_B_BFILE" "OCI_B_CFILEE" "OCI_B_CLOB" "OCI_B_BLOB"</span>
+<span class="linecomment">;        "OCI_B_ROWID" "OCI_B_CURSOR" "OCI_B_BIN" "OCI_ASSOC" "OCI_NUM"</span>
+<span class="linecomment">;        "OCI_BOTH" "OCI_RETURN_NULLS" "OCI_RETURN_LOBS"</span>
+<span class="linecomment">;        "OCI_DTYPE_FILE" "OCI_DTYPE_LOB" "OCI_DTYPE_ROWID" "OCI_D_FILE"</span>
+<span class="linecomment">;        "OCI_D_LOB" "OCI_D_ROWID" "ODBC_TYPE" "ODBC_BINMODE_PASSTHRU"</span>
+<span class="linecomment">;        "ODBC_BINMODE_RETURN" "ODBC_BINMODE_CONVERT" "SQL_ODBC_CURSORS"</span>
+<span class="linecomment">;        "SQL_CUR_USE_DRIVER" "SQL_CUR_USE_IF_NEEDED" "SQL_CUR_USE_ODBC"</span>
+<span class="linecomment">;        "SQL_CONCURRENCY" "SQL_CONCUR_READ_ONLY" "SQL_CONCUR_LOCK"</span>
+<span class="linecomment">;        "SQL_CONCUR_ROWVER" "SQL_CONCUR_VALUES" "SQL_CURSOR_TYPE"</span>
+<span class="linecomment">;        "SQL_CURSOR_FORWARD_ONLY" "SQL_CURSOR_KEYSET_DRIVEN"</span>
+<span class="linecomment">;        "SQL_CURSOR_DYNAMIC" "SQL_CURSOR_STATIC" "SQL_KEYSET_SIZE"</span>
+<span class="linecomment">;        "SQL_CHAR" "SQL_VARCHAR" "SQL_LONGVARCHAR" "SQL_DECIMAL"</span>
+<span class="linecomment">;        "SQL_NUMERIC" "SQL_BIT" "SQL_TINYINT" "SQL_SMALLINT"</span>
+<span class="linecomment">;        "SQL_INTEGER" "SQL_BIGINT" "SQL_REAL" "SQL_FLOAT" "SQL_DOUBLE"</span>
+<span class="linecomment">;        "SQL_BINARY" "SQL_VARBINARY" "SQL_LONGVARBINARY" "SQL_DATE"</span>
+<span class="linecomment">;        "SQL_TIME" "SQL_TIMESTAMP" "SQL_TYPE_DATE" "SQL_TYPE_TIME"</span>
+<span class="linecomment">;        "SQL_TYPE_TIMESTAMP" "SQL_BEST_ROWID" "SQL_ROWVER"</span>
+<span class="linecomment">;        "SQL_SCOPE_CURROW" "SQL_SCOPE_TRANSACTION" "SQL_SCOPE_SESSION"</span>
+<span class="linecomment">;        "SQL_NO_NULLS" "SQL_NULLABLE" "SQL_INDEX_UNIQUE"</span>
+<span class="linecomment">;        "SQL_INDEX_ALL" "SQL_ENSURE" "SQL_QUICK"</span>
+<span class="linecomment">;        "X509_PURPOSE_SSL_CLIENT" "X509_PURPOSE_SSL_SERVER"</span>
+<span class="linecomment">;        "X509_PURPOSE_NS_SSL_SERVER" "X509_PURPOSE_SMIME_SIGN"</span>
+<span class="linecomment">;        "X509_PURPOSE_SMIME_ENCRYPT" "X509_PURPOSE_CRL_SIGN"</span>
+<span class="linecomment">;        "X509_PURPOSE_ANY" "PKCS7_DETACHED" "PKCS7_TEXT"</span>
+<span class="linecomment">;        "PKCS7_NOINTERN" "PKCS7_NOVERIFY" "PKCS7_NOCHAIN"</span>
+<span class="linecomment">;        "PKCS7_NOCERTS" "PKCS7_NOATTR" "PKCS7_BINARY" "PKCS7_NOSIGS"</span>
+<span class="linecomment">;        "OPENSSL_PKCS1_PADDING" "OPENSSL_SSLV23_PADDING"</span>
+<span class="linecomment">;        "OPENSSL_NO_PADDING" "OPENSSL_PKCS1_OAEP_PADDING"</span>
+<span class="linecomment">;        "ORA_BIND_INOUT" "ORA_BIND_IN" "ORA_BIND_OUT"</span>
+<span class="linecomment">;        "ORA_FETCHINTO_ASSOC" "ORA_FETCHINTO_NULLS"</span>
+<span class="linecomment">;        "PREG_PATTERN_ORDER" "PREG_SET_ORDER" "PREG_SPLIT_NO_EMPTY"</span>
+<span class="linecomment">;        "PREG_SPLIT_DELIM_CAPTURE"</span>
+<span class="linecomment">;        "PGSQL_ASSOC" "PGSQL_NUM" "PGSQL_BOTH"</span>
+<span class="linecomment">;        "PRINTER_COPIES" "PRINTER_MODE" "PRINTER_TITLE"</span>
+<span class="linecomment">;        "PRINTER_DEVICENAME" "PRINTER_DRIVERVERSION"</span>
+<span class="linecomment">;        "PRINTER_RESOLUTION_Y" "PRINTER_RESOLUTION_X" "PRINTER_SCALE"</span>
+<span class="linecomment">;        "PRINTER_BACKGROUND_COLOR" "PRINTER_PAPER_LENGTH"</span>
+<span class="linecomment">;        "PRINTER_PAPER_WIDTH" "PRINTER_PAPER_FORMAT"</span>
+<span class="linecomment">;        "PRINTER_FORMAT_CUSTOM" "PRINTER_FORMAT_LETTER"</span>
+<span class="linecomment">;        "PRINTER_FORMAT_LEGAL" "PRINTER_FORMAT_A3" "PRINTER_FORMAT_A4"</span>
+<span class="linecomment">;        "PRINTER_FORMAT_A5" "PRINTER_FORMAT_B4" "PRINTER_FORMAT_B5"</span>
+<span class="linecomment">;        "PRINTER_FORMAT_FOLIO" "PRINTER_ORIENTATION"</span>
+<span class="linecomment">;        "PRINTER_ORIENTATION_PORTRAIT" "PRINTER_ORIENTATION_LANDSCAPE"</span>
+<span class="linecomment">;        "PRINTER_TEXT_COLOR" "PRINTER_TEXT_ALIGN" "PRINTER_TA_BASELINE"</span>
+<span class="linecomment">;        "PRINTER_TA_BOTTOM" "PRINTER_TA_TOP" "PRINTER_TA_CENTER"</span>
+<span class="linecomment">;        "PRINTER_TA_LEFT" "PRINTER_TA_RIGHT" "PRINTER_PEN_SOLID"</span>
+<span class="linecomment">;        "PRINTER_PEN_DASH" "PRINTER_PEN_DOT" "PRINTER_PEN_DASHDOT"</span>
+<span class="linecomment">;        "PRINTER_PEN_DASHDOTDOT" "PRINTER_PEN_INVISIBLE"</span>
+<span class="linecomment">;        "PRINTER_BRUSH_SOLID" "PRINTER_BRUSH_CUSTOM"</span>
+<span class="linecomment">;        "PRINTER_BRUSH_DIAGONAL" "PRINTER_BRUSH_CROSS"</span>
+<span class="linecomment">;        "PRINTER_BRUSH_DIAGCROSS" "PRINTER_BRUSH_FDIAGONAL"</span>
+<span class="linecomment">;        "PRINTER_BRUSH_HORIZONTAL" "PRINTER_BRUSH_VERTICAL"</span>
+<span class="linecomment">;        "PRINTER_FW_THIN" "PRINTER_FW_ULTRALIGHT" "PRINTER_FW_LIGHT"</span>
+<span class="linecomment">;        "PRINTER_FW_NORMAL" "PRINTER_FW_MEDIUM" "PRINTER_FW_BOLD"</span>
+<span class="linecomment">;        "PRINTER_FW_ULTRABOLD" "PRINTER_FW_HEAVY" "PRINTER_ENUM_LOCAL"</span>
+<span class="linecomment">;        "PRINTER_ENUM_NAME" "PRINTER_ENUM_SHARED"</span>
+<span class="linecomment">;        "PRINTER_ENUM_DEFAULT" "PRINTER_ENUM_CONNECTIONS"</span>
+<span class="linecomment">;        "PRINTER_ENUM_NETWORK" "PRINTER_ENUM_REMOTE" "PSPELL_FAST"</span>
+<span class="linecomment">;        "PSPELL_NORMAL" "PSPELL_BAD_SPELLERS" "PSPELL_RUN_TOGETHER"</span>
+<span class="linecomment">;        "SID" "SID" "AF_UNIX" "AF_INET" "SOCK_STREAM" "SOCK_DGRAM"</span>
+<span class="linecomment">;        "SOCK_RAW" "SOCK_SEQPACKET" "SOCK_RDM" "MSG_OOB" "MSG_WAITALL"</span>
+<span class="linecomment">;        "MSG_PEEK" "MSG_DONTROUTE" "SO_DEBUG" "SO_REUSEADDR"</span>
+<span class="linecomment">;        "SO_KEEPALIVE" "SO_DONTROUTE" "SO_LINGER" "SO_BROADCAST"</span>
+<span class="linecomment">;        "SO_OOBINLINE" "SO_SNDBUF" "SO_RCVBUF" "SO_SNDLOWAT"</span>
+<span class="linecomment">;        "SO_RCVLOWAT" "SO_SNDTIMEO" "SO_RCVTIMEO" "SO_TYPE" "SO_ERROR"</span>
+<span class="linecomment">;        "SOL_SOCKET" "PHP_NORMAL_READ" "PHP_BINARY_READ"</span>
+<span class="linecomment">;        "PHP_SYSTEM_READ" "SOL_TCP" "SOL_UDP" "MOD_COLOR" "MOD_MATRIX"</span>
+<span class="linecomment">;        "TYPE_PUSHBUTTON" "TYPE_MENUBUTTON" "BSHitTest" "BSDown"</span>
+<span class="linecomment">;        "BSOver" "BSUp" "OverDowntoIdle" "IdletoOverDown"</span>
+<span class="linecomment">;        "OutDowntoIdle" "OutDowntoOverDown" "OverDowntoOutDown"</span>
+<span class="linecomment">;        "OverUptoOverDown" "OverUptoIdle" "IdletoOverUp" "ButtonEnter"</span>
+<span class="linecomment">;        "ButtonExit" "MenuEnter" "MenuExit" "XML_ERROR_NONE"</span>
+<span class="linecomment">;        "XML_ERROR_NO_MEMORY" "XML_ERROR_SYNTAX"</span>
+<span class="linecomment">;        "XML_ERROR_NO_ELEMENTS" "XML_ERROR_INVALID_TOKEN"</span>
+<span class="linecomment">;        "XML_ERROR_UNCLOSED_TOKEN" "XML_ERROR_PARTIAL_CHAR"</span>
+<span class="linecomment">;        "XML_ERROR_TAG_MISMATCH" "XML_ERROR_DUPLICATE_ATTRIBUTE"</span>
+<span class="linecomment">;        "XML_ERROR_JUNK_AFTER_DOC_ELEMENT" "XML_ERROR_PARAM_ENTITY_REF"</span>
+<span class="linecomment">;        "XML_ERROR_UNDEFINED_ENTITY" "XML_ERROR_RECURSIVE_ENTITY_REF"</span>
+<span class="linecomment">;        "XML_ERROR_ASYNC_ENTITY" "XML_ERROR_BAD_CHAR_REF"</span>
+<span class="linecomment">;        "XML_ERROR_BINARY_ENTITY_REF"</span>
+<span class="linecomment">;        "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF"</span>
+<span class="linecomment">;        "XML_ERROR_MISPLACED_XML_PI" "XML_ERROR_UNKNOWN_ENCODING"</span>
+<span class="linecomment">;        "XML_ERROR_INCORRECT_ENCODING"</span>
+<span class="linecomment">;        "XML_ERROR_UNCLOSED_CDATA_SECTION"</span>
+<span class="linecomment">;        "XML_ERROR_EXTERNAL_ENTITY_HANDLING" "XML_OPTION_CASE_FOLDING"</span>
+<span class="linecomment">;        "XML_OPTION_TARGET_ENCODING" "XML_OPTION_SKIP_TAGSTART"</span>
+<span class="linecomment">;        "XML_OPTION_SKIP_WHITE" "YPERR_BADARGS" "YPERR_BADDB"</span>
+<span class="linecomment">;        "YPERR_BUSY" "YPERR_DOMAIN" "YPERR_KEY" "YPERR_MAP"</span>
+<span class="linecomment">;        "YPERR_NODOM" "YPERR_NOMORE" "YPERR_PMAP" "YPERR_RESRC"</span>
+<span class="linecomment">;        "YPERR_RPC" "YPERR_YPBIND" "YPERR_YPERR" "YPERR_YPSERV"</span>
+<span class="linecomment">;        "YPERR_VERS" "FORCE_GZIP" "FORCE_DEFLATE"</span>
+
+       <span class="linecomment">;; PEAR constants</span>
+<span class="linecomment">;        "PEAR_ERROR_RETURN" "PEAR_ERROR_PRINT" "PEAR_ERROR_TRIGGER"</span>
+<span class="linecomment">;        "PEAR_ERROR_DIE" "PEAR_ERROR_CALLBACK" "OS_WINDOWS" "OS_UNIX"</span>
+<span class="linecomment">;        "PEAR_OS" "DB_OK" "DB_ERROR" "DB_ERROR_SYNTAX"</span>
+<span class="linecomment">;        "DB_ERROR_CONSTRAINT" "DB_ERROR_NOT_FOUND"</span>
+<span class="linecomment">;        "DB_ERROR_ALREADY_EXISTS" "DB_ERROR_UNSUPPORTED"</span>
+<span class="linecomment">;        "DB_ERROR_MISMATCH" "DB_ERROR_INVALID" "DB_ERROR_NOT_CAPABLE"</span>
+<span class="linecomment">;        "DB_ERROR_TRUNCATED" "DB_ERROR_INVALID_NUMBER"</span>
+<span class="linecomment">;        "DB_ERROR_INVALID_DATE" "DB_ERROR_DIVZERO"</span>
+<span class="linecomment">;        "DB_ERROR_NODBSELECTED" "DB_ERROR_CANNOT_CREATE"</span>
+<span class="linecomment">;        "DB_ERROR_CANNOT_DELETE" "DB_ERROR_CANNOT_DROP"</span>
+<span class="linecomment">;        "DB_ERROR_NOSUCHTABLE" "DB_ERROR_NOSUCHFIELD"</span>
+<span class="linecomment">;        "DB_ERROR_NEED_MORE_DATA" "DB_ERROR_NOT_LOCKED"</span>
+<span class="linecomment">;        "DB_ERROR_VALUE_COUNT_ON_ROW" "DB_ERROR_INVALID_DSN"</span>
+<span class="linecomment">;        "DB_ERROR_CONNECT_FAILED" "DB_WARNING" "DB_WARNING_READ_ONLY"</span>
+<span class="linecomment">;        "DB_PARAM_SCALAR" "DB_PARAM_OPAQUE" "DB_BINMODE_PASSTHRU"</span>
+<span class="linecomment">;        "DB_BINMODE_RETURN" "DB_BINMODE_CONVERT" "DB_FETCHMODE_DEFAULT"</span>
+<span class="linecomment">;        "DB_FETCHMODE_ORDERED" "DB_FETCHMODE_ASSOC"</span>
+<span class="linecomment">;        "DB_FETCHMODE_FLIPPED" "DB_GETMODE_ORDERED" "DB_GETMODE_ASSOC"</span>
+<span class="linecomment">;        "DB_GETMODE_FLIPPED" "DB_TABLEINFO_ORDER"</span>
+<span class="linecomment">;        "DB_TABLEINFO_ORDERTABLE" "DB_TABLEINFO_FULL"</span>
+
+       )))
+  "<span class="quote">PHP constants.</span>")
+
+(defconst php-keywords
+  (eval-when-compile
+    (regexp-opt
+     <span class="linecomment">;; "class", "new" and "extends" get special treatment</span>
+     <span class="linecomment">;; "case" and  "default" get special treatment elsewhere</span>
+     '("<span class="quote">and</span>" "<span class="quote">as</span>" "<span class="quote">break</span>" "<span class="quote">continue</span>" "<span class="quote">declare</span>" "<span class="quote">do</span>" "<span class="quote">echo</span>" "<span class="quote">else</span>" "<span class="quote">elseif</span>"
+       "<span class="quote">endfor</span>" "<span class="quote">endforeach</span>" "<span class="quote">endif</span>" "<span class="quote">endswitch</span>" "<span class="quote">endwhile</span>" "<span class="quote">exit</span>"
+       "<span class="quote">extends</span>" "<span class="quote">for</span>" "<span class="quote">foreach</span>" "<span class="quote">global</span>" "<span class="quote">if</span>" "<span class="quote">include</span>" "<span class="quote">include_once</span>"
+       "<span class="quote">next</span>" "<span class="quote">or</span>" "<span class="quote">require</span>" "<span class="quote">require_once</span>" "<span class="quote">return</span>" "<span class="quote">static</span>" "<span class="quote">switch</span>"
+       "<span class="quote">then</span>" "<span class="quote">var</span>" "<span class="quote">while</span>" "<span class="quote">xor</span>" "<span class="quote">private</span>" "<span class="quote">throw</span>" "<span class="quote">catch</span>" "<span class="quote">try</span>"
+       "<span class="quote">instanceof</span>" "<span class="quote">catch all</span>" "<span class="quote">finally</span>")))
+  "<span class="quote">PHP keywords.</span>")
+
+(defconst php-identifier
+  (eval-when-compile
+    '"<span class="quote">[a-zA-Z\_\x7f-\xff][a-zA-Z0-9\_\x7f-\xff]*</span>")
+  "<span class="quote">Characters in a PHP identifier.</span>")
+
+(defconst php-types
+  (eval-when-compile
+    (regexp-opt '("<span class="quote">array</span>" "<span class="quote">bool</span>" "<span class="quote">boolean</span>" "<span class="quote">char</span>" "<span class="quote">const</span>" "<span class="quote">double</span>" "<span class="quote">float</span>"
+                  "<span class="quote">int</span>" "<span class="quote">integer</span>" "<span class="quote">long</span>" "<span class="quote">mixed</span>" "<span class="quote">object</span>" "<span class="quote">real</span>"
+                  "<span class="quote">string</span>")))
+  "<span class="quote">PHP types.</span>")
+
+(defconst php-superglobals
+  (eval-when-compile
+    (regexp-opt '("<span class="quote">_GET</span>" "<span class="quote">_POST</span>" "<span class="quote">_COOKIE</span>" "<span class="quote">_SESSION</span>" "<span class="quote">_ENV</span>" "<span class="quote">GLOBALS</span>"
+                  "<span class="quote">_SERVER</span>" "<span class="quote">_FILES</span>" "<span class="quote">_REQUEST</span>")))
+  "<span class="quote">PHP superglobal variables.</span>")
+
+<span class="linecomment">;; Set up font locking</span>
+(defconst php-font-lock-keywords-1
+  (list
+   <span class="linecomment">;; Fontify constants</span>
+   (cons
+    (concat "<span class="quote">\\&lt;\\(</span>" php-constants "<span class="quote">\\)\\&gt;</span>")
+    'font-lock-constant-face)
+
+   <span class="linecomment">;; Fontify keywords</span>
+   (cons
+    (concat "<span class="quote">\\&lt;\\(</span>" php-keywords "<span class="quote">\\)\\&gt;</span>")
+    'font-lock-keyword-face)
+
+   <span class="linecomment">;; Fontify keywords and targets, and case default tags.</span>
+   (list "<span class="quote">\\&lt;\\(break\\|case\\|continue\\)\\&gt;[ \t]*\\(-?\\(?:\\sw\\|\\s_\\)+\\)?</span>"
+         '(1 font-lock-keyword-face) '(2 font-lock-constant-face t t))
+   <span class="linecomment">;; This must come after the one for keywords and targets.</span>
+   '("<span class="quote">:</span>" ("<span class="quote">^[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:[ \t]*$</span>"
+          (beginning-of-line) (end-of-line)
+          (1 font-lock-constant-face)))
+
+   <span class="linecomment">;; treat 'print' as keyword only when not used like a function name</span>
+   '("<span class="quote">\\&lt;print\\s-*(</span>" . php-default-face)
+   '("<span class="quote">\\&lt;print\\&gt;</span>" . font-lock-keyword-face)
+
+   <span class="linecomment">;; Fontify PHP tag</span>
+   '("<span class="quote">&lt;\\?\\(php\\)?</span>" . font-lock-constant-face)
+   '("<span class="quote">\\?&gt;</span>" . font-lock-constant-face)
+
+   <span class="linecomment">;; Fontify ASP-style tag</span>
+   '("<span class="quote">&lt;\\%\\(=\\)?</span>" . font-lock-constant-face)
+   '("<span class="quote">\\%&gt;</span>" . font-lock-constant-face)
+
+   )
+  "<span class="quote">Subdued level highlighting for PHP mode.</span>")
+
+(defconst php-font-lock-keywords-2
+  (append
+   php-font-lock-keywords-1
+   (list
+
+    <span class="linecomment">;; class declaration</span>
+    '("<span class="quote">[^_]*\\&lt;\\(class\\|interface\\)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?</span>"
+      (1 font-lock-keyword-face) (2 font-lock-type-face nil t))
+    <span class="linecomment">;; handle several words specially, to include following word,</span>
+    <span class="linecomment">;; thereby excluding it from unknown-symbol checks later</span>
+    <span class="linecomment">;; FIX to handle implementing multiple</span>
+    <span class="linecomment">;; currently breaks on "class Foo implements Bar, Baz"</span>
+    '("<span class="quote">\\&lt;\\(new\\|extends\\|implements\\)\\s-+\\$?\\(\\(?:\\sw\\|\\s_\\)+\\)</span>"
+      (1 font-lock-keyword-face) (2 font-lock-type-face))
+
+    <span class="linecomment">;; function declaration</span>
+    '("<span class="quote">\\&lt;\\(function\\)\\s-+&?\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(</span>"
+      (1 font-lock-keyword-face)
+      (2 font-lock-function-name-face nil t))
+
+    <span class="linecomment">;; class hierarchy</span>
+    '("<span class="quote">\\(self\\|parent\\)\\W</span>" (1 font-lock-constant-face nil nil))
+
+    <span class="linecomment">;; method and variable features</span>
+    '("<span class="quote">\\&lt;\\(private\\|protected\\|public\\)\\s-+\\$?\\(?:\\sw\\|\\s_\\)+</span>"
+      (1 font-lock-keyword-face))
+
+    <span class="linecomment">;; method features</span>
+    '("<span class="quote">^[ \t]*\\(abstract\\|static\\|final\\)\\s-+\\$?\\(?:\\sw\\|\\s_\\)+</span>"
+      (1 font-lock-keyword-face))
+
+    <span class="linecomment">;; variable features</span>
+    '("<span class="quote">^[ \t]*\\(static\\|const\\)\\s-+\\$?\\(?:\\sw\\|\\s_\\)+</span>"
+      (1 font-lock-keyword-face))
+    ))
+  "<span class="quote">Medium level highlighting for PHP mode.</span>")
+
+(defconst php-font-lock-keywords-3
+  (append
+   php-font-lock-keywords-2
+   `(
+     <span class="linecomment">;; &lt;word&gt; or &lt;/word&gt; for HTML</span>
+     <span class="linecomment">;;'("&lt;/?\\sw+[^&gt; ]*&gt;" . font-lock-constant-face)</span>
+     <span class="linecomment">;;'("&lt;/?\\sw+[^&gt;]*" . font-lock-constant-face)</span>
+     <span class="linecomment">;;'("&lt;!DOCTYPE" . font-lock-constant-face)</span>
+     ("<span class="quote">&lt;/?[a-z!:]+</span>" . font-lock-constant-face)
+
+     <span class="linecomment">;; HTML &gt;</span>
+     ("<span class="quote">&lt;[^&gt;]*\\(&gt;\\)</span>" (1 font-lock-constant-face))
+
+     <span class="linecomment">;; HTML tags</span>
+     ("<span class="quote">\\(&lt;[a-z]+\\)[[:space:]]+\\([a-z:]+=\\)[^&gt;]*?</span>" (1 font-lock-constant-face) (2 font-lock-constant-face) )
+     ("<span class="quote">\"[[:space:]]+\\([a-z:]+=\\)</span>" (1 font-lock-constant-face))
+
+     <span class="linecomment">;; HTML entities</span>
+     <span class="linecomment">;;'("&\\w+;" . font-lock-variable-name-face)</span>
+
+     <span class="linecomment">;; warn about '$' immediately after -&gt;</span>
+     ,@(if php-mode-dollar-property-warning
+           '("<span class="quote">\\$\\(?:\\sw\\|\\s_\\)+-&gt;\\s-*\\(\\$\\)\\(\\(?:\\sw\\|\\s_\\)+\\)</span>"
+             (1 font-lock-warning-face) (2 php-default-face)))
+
+     <span class="linecomment">;; warn about $word.word -- it could be a valid concatenation,</span>
+     <span class="linecomment">;; but without any spaces we'll assume $word-&gt;word was meant.</span>
+     ,@(if php-mode-dot-property-warning
+           '("<span class="quote">\\$\\(?:\\sw\\|\\s_\\)+\\(\\.\\)\\sw</span>" 1 font-lock-warning-face))
+
+     <span class="linecomment">;; Warn about ==&gt; instead of =&gt;</span>
+     ("<span class="quote">==+&gt;</span>" . font-lock-warning-face)
+
+     <span class="linecomment">;; exclude casts from bare-word treatment (may contain spaces)</span>
+     (,(concat "<span class="quote">(\\s-*\\(</span>" php-types "<span class="quote">\\)\\s-*)</span>") 1 font-lock-type-face)
+
+     <span class="linecomment">;; PHP5: function declarations may contain classes as parameters type</span>
+     (,(concat
+        "<span class="quote">[(,]\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-+&?\\$\\(?:\\sw\\|\\s_\\)+\\&gt;</span>")
+      1 font-lock-type-face)
+
+     <span class="linecomment">;; Fontify variables and function calls</span>
+     ("<span class="quote">\\$\\(this\\|that\\)\\W</span>" (1 font-lock-constant-face nil nil))
+     (,(concat "<span class="quote">\\$\\(</span>" php-superglobals "<span class="quote">\\)\\W</span>")
+      (1 font-lock-constant-face nil nil)) <span class="linecomment">; $_GET & co</span>
+     ("<span class="quote">\\$\\(\\(?:\\sw\\|\\s_\\)+\\)</span>" (1 font-lock-variable-name-face)) <span class="linecomment">; $variable</span>
+     ("<span class="quote">-&gt;\\(\\(?:\\sw\\|\\s_\\)+\\)</span>" (1 font-lock-variable-name-face t t)) <span class="linecomment">; -&gt;variable</span>
+     ("<span class="quote">-&gt;\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(</span>" . (1 php-default-face t t)) <span class="linecomment">; -&gt;function_call</span>
+     ("<span class="quote">\\(\\(?:\\sw\\|\\s_\\)+\\)::\\(?:\\sw\\|\\s_\\)+\\s-*(?</span>" . (1 font-lock-type-face)) <span class="linecomment">; class::member</span>
+     ("<span class="quote">::\\(\\(?:\\sw\\|\\s_\\)+\\&gt;[^(]\\)</span>" . (1 php-default-face)) <span class="linecomment">; class::constant</span>
+     ("<span class="quote">\\&lt;\\(?:\\sw\\|\\s_\\)+\\s-*[[(]</span>" . php-default-face) <span class="linecomment">; word( or word[</span>
+     ("<span class="quote">\\&lt;[0-9]+</span>" . php-default-face)   <span class="linecomment">; number (also matches word)</span>
+
+     <span class="linecomment">;; Warn on any words not already fontified</span>
+     ,@(if php-mode-warn-on-unmatched
+           '("<span class="quote">\\&lt;\\(?:\\sw\\|\\s_\\)+\\&gt;</span>" . font-lock-warning-face))
+
+     )
+   )
+  "<span class="quote">Gauchy level highlighting for PHP mode.</span>")
+
+<span class="linecomment">;; Define the imenu-generic-expression for PHP mode.</span>
+<span class="linecomment">;; To use, execute M-x imenu, then click on Functions or Classes,</span>
+<span class="linecomment">;; then select given function/class name to go to its definition.</span>
+<span class="linecomment">;; [Contributed by Gerrit Riessen]</span>
+(defvar php-imenu-generic-expression
+ '(
+   ("<span class="quote">All Functions</span>"
+    "<span class="quote">^\\s-*function\\s-+\\([[:alnum:]_]+\\)\\s-*(</span>" 1)
+   ("<span class="quote">Classes</span>"
+    "<span class="quote">^\\s-*class\\s-+\\([[:alnum:]_]+\\)\\s-*</span>" 1)
+   ("<span class="quote">Public Methods</span>"
+    "<span class="quote">^\\s-*public function\\s-+\\([[:alnum:]_]+\\)\\s-*(</span>" 1)
+   ("<span class="quote">Protected Methods</span>"
+    "<span class="quote">^\\s-*protected function\\s-+\\([[:alnum:]_]+\\)\\s-*(</span>" 1)
+   ("<span class="quote">Private Methods</span>"
+    "<span class="quote">^\\s-*private function\\s-+\\([[:alnum:]_]+\\)\\s-*(</span>" 1)
+   )
+ "<span class="quote">Imenu generic expression for PHP Mode. See `imenu-generic-expression'.</span>"
+ )
+
+(defconst php-block-stmt-1-kwds '("<span class="quote">do</span>" "<span class="quote">else</span>" "<span class="quote">finally</span>" "<span class="quote">try</span>"))
+(defconst php-block-stmt-2-kwds
+  '("<span class="quote">for</span>" "<span class="quote">if</span>" "<span class="quote">while</span>" "<span class="quote">switch</span>" "<span class="quote">foreach</span>" "<span class="quote">elseif</span>"  "<span class="quote">catch all</span>"))
+
+(defconst php-block-stmt-1-key
+  (regexp-opt php-block-stmt-1-kwds))
+(defconst php-block-stmt-2-key
+  (regexp-opt php-block-stmt-2-kwds))
+
+(defconst php-class-decl-kwds '("<span class="quote">class</span>" "<span class="quote">interface</span>"))
+
+(defconst php-class-key
+  (concat
+   "<span class="quote">\\(</span>" (regexp-opt php-class-decl-kwds) "<span class="quote">\\)\\s +</span>"
+   c-symbol-key                                 <span class="linecomment">;; Class name.</span>
+   "<span class="quote">\\(\\s *extends\\s *</span>" c-symbol-key "<span class="quote">\\)?</span>"   <span class="linecomment">;; Name of superclass.</span>
+   "<span class="quote">\\(\\s *implements *[^{]+{\\)?</span>")) <span class="linecomment">;; List of any adopted protocols.</span>
+
+<span class="linecomment">;; Create "php-default-face" symbol for GNU Emacs so that both XEmacs</span>
+<span class="linecomment">;; and GNU emacs can refer to the default face.</span>
+(unless (boundp 'php-default-face)
+   (defvar php-default-face 'php-default-face))
+
+<span class="linecomment">;; Create faces for XEmacs</span>
+(when (featurep 'xemacs)
+  (unless (boundp 'font-lock-keyword-face)
+    (copy-face 'bold 'font-lock-keyword-face))
+  (unless (boundp 'font-lock-constant-face)
+    (copy-face 'font-lock-keyword-face 'font-lock-constant-face)))
+
+(provide 'php-mode)
+
+<span class="linecomment">;;; php-mode.el ends here</span></span></pre></div><div class="wrapper close"></div></div><div class="footer"><hr /><span class="gotobar bar"><a class="local" href="http://www.emacswiki.org/emacs/SiteMap">SiteMap</a> <a class="local" href="http://www.emacswiki.org/emacs/Search">Search</a> <a class="local" href="http://www.emacswiki.org/emacs/ElispArea">ElispArea</a> <a class="local" href="http://www.emacswiki.org/emacs/HowTo">HowTo</a> <a class="local" href="http://www.emacswiki.org/emacs/Glossary">Glossary</a> <a class="local" href="http://www.emacswiki.org/emacs/RecentChanges">RecentChanges</a> <a class="local" href="http://www.emacswiki.org/emacs/News">News</a> <a class="local" href="http://www.emacswiki.org/emacs/Problems">Problems</a> <a class="local" href="http://www.emacswiki.org/emacs/Suggestions">Suggestions</a> </span><span class="translation bar"><br />  <a class="translation new" rel="nofollow" href="http://www.emacswiki.org/emacs?action=translate;id=php-mode-improved.el;missing=de_en_es_fr_it_ja_ko_pt_ru_se_zh">Add Translation</a></span><span class="edit bar"><br /> <a class="comment local edit" accesskey="c" href="http://www.emacswiki.org/emacs/Comments_on_php-mode-improved.el">Talk</a> <a class="edit" accesskey="e" title="Click to edit this page" rel="nofollow" href="http://www.emacswiki.org/emacs?action=edit;id=php-mode-improved.el">Edit this page</a> <a class="history" rel="nofollow" href="http://www.emacswiki.org/emacs?action=history;id=php-mode-improved.el">View other revisions</a> <a class="admin" rel="nofollow" href="http://www.emacswiki.org/emacs?action=admin;id=php-mode-improved.el">Administration</a></span><span class="time"><br /> Last edited 2008-09-01 21:44 UTC by <a class="author" title="from host86-132-139-157.range86-132.btcentralplus.com" href="http://www.emacswiki.org/emacs/DavidHouse">DavidHouse</a> <a class="diff" rel="nofollow" href="http://www.emacswiki.org/emacs?action=browse;diff=2;id=php-mode-improved.el">(diff)</a></span><form method="get" action="http://www.emacswiki.org/cgi-bin/emacs" enctype="multipart/form-data" accept-charset="utf-8" class="search">
+<p><label for="search">Search:</label> <input type="text" name="search"  size="20" accesskey="f" id="search" /> <label for="searchlang">Language:</label> <input type="text" name="lang"  size="10" id="searchlang" /> <input type="submit" name="dosearch" value="Go!" /></p></form><div style="float:right; margin-left:1ex;">
+<!-- Creative Commons License -->
+<a class="licence" href="http://creativecommons.org/licenses/GPL/2.0/"><img alt="CC-GNU GPL" style="border:none" src="/pics/cc-GPL-a.png" /></a>
+<!-- /Creative Commons License -->
+</div>
+
+<!--
+<rdf:RDF xmlns="http://web.resource.org/cc/"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+<Work rdf:about="">
+   <license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
+  <dc:type rdf:resource="http://purl.org/dc/dcmitype/Software" />
+</Work>
+
+<License rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
+   <permits rdf:resource="http://web.resource.org/cc/Reproduction" />
+   <permits rdf:resource="http://web.resource.org/cc/Distribution" />
+   <requires rdf:resource="http://web.resource.org/cc/Notice" />
+   <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+   <requires rdf:resource="http://web.resource.org/cc/ShareAlike" />
+   <requires rdf:resource="http://web.resource.org/cc/SourceCode" />
+</License>
+</rdf:RDF>
+-->
+
+<p class="legal">
+This work is licensed to you under version 2 of the
+<a href="http://www.gnu.org/">GNU</a> <a href="/GPL">General Public License</a>.
+Alternatively, you may choose to receive this work under any other
+license that grants the right to use, copy, modify, and/or distribute
+the work, as long as that license imposes the restriction that
+derivative works have to grant the same rights and impose the same
+restriction. For example, you may choose to receive this work under
+the
+<a href="http://www.gnu.org/">GNU</a>
+<a href="/FDL">Free Documentation License</a>, the
+<a href="http://creativecommons.org/">CreativeCommons</a>
+<a href="http://creativecommons.org/licenses/sa/1.0/">ShareAlike</a>
+License, the XEmacs manual license, or
+<a href="/OLD">similar licenses</a>.
+</p>
+</div>
+</body>
+</html>
[from now] 2013/11/20 10:15:07

diff --git "a/.emacs.d/elisp/package-install.el\n" "b/.emacs.d/elisp/package-install.el\n"
new file mode 100644
index 0000000..e69de29
[from now] 2013/11/20 10:16:20

diff --git a/.emacs.d/el-get/.loaddefs.el b/.emacs.d/el-get/.loaddefs.el
new file mode 100644
index 0000000..42b8af2
--- /dev/null
+++ b/.emacs.d/el-get/.loaddefs.el
@@ -0,0 +1,69 @@
+;;; .loaddefs.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+
+;;;### (autoloads (el-get-checksum el-get-make-recipes el-get-cd
+;;;;;;  el-get-self-update el-get-update-all el-get-version) "el-get"
+;;;;;;  "el-get/el-get.el" (21132 3425))
+;;; Generated autoloads from el-get/el-get.el
+
+(autoload 'el-get-version "el-get" "\
+Message the current el-get version
+
+\(fn)" t nil)
+
+(autoload 'el-get-update-all "el-get" "\
+Performs update of all installed packages.
+
+\(fn &optional NO-PROMPT)" t nil)
+
+(autoload 'el-get-self-update "el-get" "\
+Update el-get itself.  The standard recipe takes care of reloading the code.
+
+\(fn)" t nil)
+
+(autoload 'el-get-cd "el-get" "\
+Open dired in the package directory.
+
+\(fn PACKAGE)" t nil)
+
+(autoload 'el-get-make-recipes "el-get" "\
+Loop over `el-get-sources' and write a recipe file for each
+entry which is not a symbol and is not already a known recipe.
+
+\(fn &optional DIR)" t nil)
+
+(autoload 'el-get-checksum "el-get" "\
+Compute the checksum of the given package, and put it in the kill-ring
+
+\(fn PACKAGE &optional PACKAGE-STATUS-ALIST)" t nil)
+
+;;;***
+
+;;;### (autoloads (el-get-list-packages) "el-get-list-packages" "el-get/el-get-list-packages.el"
+;;;;;;  (21132 3425))
+;;; Generated autoloads from el-get/el-get-list-packages.el
+
+(autoload 'el-get-list-packages "el-get-list-packages" "\
+Display a list of packages.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("el-get/el-get-autoloads.el" "el-get/el-get-build.el"
+;;;;;;  "el-get/el-get-byte-compile.el" "el-get/el-get-core.el" "el-get/el-get-custom.el"
+;;;;;;  "el-get/el-get-dependencies.el" "el-get/el-get-install.el"
+;;;;;;  "el-get/el-get-methods.el" "el-get/el-get-notify.el" "el-get/el-get-recipes.el"
+;;;;;;  "el-get/el-get-status.el") (21132 3427 807931))
+
+;;;***
+
+(provide '.loaddefs)
+;; Local Variables:
+;; version-control: never
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; .loaddefs.el ends here
diff --git a/.emacs.d/el-get/.status.el b/.emacs.d/el-get/.status.el
new file mode 100644
index 0000000..d66faf6
--- /dev/null
+++ b/.emacs.d/el-get/.status.el
@@ -0,0 +1,2 @@
+((el-get status "installed" recipe
+         (:name el-get :website "https://github.com/dimitri/el-get#readme" :description "Manage the external elisp bits and pieces you depend upon." :type github :branch "4.stable" :pkgname "dimitri/el-get" :features el-get :info "." :load "el-get.el")))
diff --git a/.emacs.d/el-get/.status.el.old b/.emacs.d/el-get/.status.el.old
new file mode 100644
index 0000000..90b5a84
--- /dev/null
+++ b/.emacs.d/el-get/.status.el.old
@@ -0,0 +1 @@
+nil
\ No newline at end of file
diff --git a/.emacs.d/el-get/el-get b/.emacs.d/el-get/el-get
new file mode 160000
index 0000000..20f5d34
--- /dev/null
+++ b/.emacs.d/el-get/el-get
@@ -0,0 +1 @@
+Subproject commit 20f5d34c056f5d8b3fc35b84b0e363dc1cb529d5
[from now] 2013/11/20 10:18:24

diff --git a/.emacs.d/el-get/php-mode-improved/php-mode-improved.el.part b/.emacs.d/el-get/php-mode-improved/php-mode-improved.el.part
new file mode 100644
index 0000000..1cf9f36
--- /dev/null
+++ b/.emacs.d/el-get/php-mode-improved/php-mode-improved.el.part
@@ -0,0 +1,1263 @@
+;;; php-mode.el --- major mode for editing PHP code
+
+;; This is a version of the php-mode from http://php-mode.sourceforge.net that
+;; fixes a few bugs which make using php-mode much more palatable, namely:
+;;
+;; 1. New customisation options for some of the syntax highlighting
+;;   features. I personally use the 'Gauchy' level of syntax
+;;   highlighting -- I want variables and function calls fontified --
+;;   but there were several very annoying "features" in this level of
+;;   syntax highlighting, particularly the ones that warn you about
+;;   perfectly valid code. I've added:
+;;
+;;   * `php-mode-dollar-property-warning', which, if non-nil, warns on
+;;     $foo->$bar. (Default is nil.)
+;;   * `php-mode-dot-property-warning', which, if non-nil, warns on
+;;     $foo.bar. (Default is nil.)
+;;   * `php-mode-warn-on-unmatches', which, if non-nil, warns on
+;;     "everything else". (Default is nil.)
+;;   * `php-mode-warn-if-mumamo-off', which, if nil, suppresses the
+;;     once-per-file warning about indenting with mumamo-mode turned
+;;     off. (Default is t)
+;;
+;; 2. Bugfix in `php-show-arglist': this function no longer jumps to the
+;;   function definition if that definition is in the current buffer.
+;;
+;; 3. Bugfix: 'class' keywords at the beginning of a line are now
+;;   correctly fontified.
+;;
+;; This has been submitted to the php-mode maintainer, but I've not yet had a
+;; response.
+;;
+;; This was branched from the php-mode in nxhtml-mode, so if you have problems,
+;; download the latest nxhtml-mode, and replace related/php-mode.el in the
+;; nxhtml distribution with this file.
+;;
+;; -- David House, dmhouse@gmail.com
+
+;; Copyright (C) 1999, 2000, 2001, 2003, 2004 Turadg Aleahmad
+;;               2008 Aaron S. Hawley
+
+;; Maintainer: Aaron S. Hawley <ashawley at users.sourceforge.net>
+;; Author: Turadg Aleahmad, 1999-2004
+;; Keywords: php languages oop
+;; Created: 1999-05-17
+;; Modified: 2008-01-25T22:25:26+0100 Fri
+;; X-URL:   http://php-mode.sourceforge.net/
+
+(defconst php-mode-version-number "1.4.1a-nxhtml"
+  "PHP Mode version number.")
+
+;;; License
+
+;; This file is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 3
+;; of the License, or (at your option) any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Usage
+
+;; Put this file in your Emacs lisp path (eg. site-lisp) and add to
+;; your .emacs file:
+;;
+;;   (require 'php-mode)
+
+;; To use abbrev-mode, add lines like this:
+;;   (add-hook 'php-mode-hook
+;;     '(lambda () (define-abbrev php-mode-abbrev-table "ex" "extends")))
+
+;; To make php-mode compatible with html-mode, see http://php-mode.sf.net
+
+;; Many options available under Help:Customize
+;; Options specific to php-mode are in
+;;  Programming/Languages/Php
+;; Since it inherits much functionality from c-mode, look there too
+;;  Programming/Languages/C
+
+;;; Commentary:
+
+;; PHP mode is a major mode for editing PHP 3 and 4 source code.  It's
+;; an extension of C mode; thus it inherits all C mode's navigation
+;; functionality.  But it colors according to the PHP grammar and indents
+;; according to the PEAR coding guidelines.  It also includes a couple
+;; handy IDE-type features such as documentation search and a source
+;; and class browser.
+
+
+;;; Contributors: (in chronological order)
+
+;; Juanjo, Torsten Martinsen, Vinai Kopp, Sean Champ, Doug Marcey,
+;; Kevin Blake, Rex McMaster, Mathias Meyer, Boris Folgmann, Roland
+;; Rosenfeld, Fred Yankowski, Craig Andrews, John Keller, Ryan
+;; Sammartino, ppercot, Valentin Funk, Stig Bakken, Gregory Stark,
+;; Chris Morris, Nils Rennebarth, Gerrit Riessen, Eric Mc Sween,
+;; Ville Skytta, Giacomo Tesio, Lennart Borgman, Stefan Monnier,
+;; Aaron S. Hawley, Ian Eure, Bill Lovett, David House
+
+;;; Changelog:
+
+;; 1.4.1a-nxhtml
+;;   Made underscore be part of identifiers.
+;;
+;; 1.4.1-nxhtml
+;;   Added php-mode-to-use.
+
+;; 1.4.1
+;;   Modified `php-check-html-for-indentation' to check for multiple
+;;   mode support libraries. (Lennart Borgman)
+;;
+;; 1.4
+;;   Updated GNU GPL to version 3.  Ported to Emacs 22 (CC mode
+;;   5.31). M-x php-mode-version shows version.  Provide end-of-defun
+;;   beginning-of-defun functionality. Support add-log library.
+;;   Fix __CLASS__ constant (Ian Eure).  Allow imenu to see visibility
+;;   declarations -- "private", "public", "protected". (Bill Lovett)
+;;
+;; 1.3
+;;   Changed the definition of # using a tip from Stefan
+;;   Monnier to correct highlighting and indentation. (Lennart Borgman)
+;;   Changed the highlighting of the HTML part. (Lennart Borgman)
+;;
+;; 1.2
+;;   Implemented php-show-arglist, C-. (Engelke Eschner)
+;;   Implemented php-complete-function, M-tab (Engelke Eschner)
+;;   Re-enabled # comment detection in GNU Emacs (Urban Müller)
+;;   Fixed some keybindings and default settings (Engelke Eschner)
+;;
+;; 1.1
+;;   Added PHP5 support (Giacomo Tesio)
+;;     known problem: doesn't highlight after first 'implements'
+;;   Better XEmacs compatibility (imenu, regexp, and comments!) (Ville Skytta)
+;;   Improvement to php-conditional-key regexp (Eric Mc Sween)
+
+;; 1.05
+;;   Incorporated speedbar defs by Gerrit Riessen
+;;   Add "foreach" to conditional introducing keywords (Nils Rennebarth)
+;;   Cleared the Changelog
+;;   Moved contribution credits into comments above
+
+
+;;; Code:
+
+(require 'speedbar)
+(require 'font-lock)
+(require 'cc-mode)
+(require 'custom)
+(require 'etags)
+(eval-when-compile
+  (require 'regexp-opt))
+
+;; Local variables
+(defgroup php nil
+  "Major mode `php-mode' for editing PHP code."
+  :prefix "php-"
+  :group 'languages)
+
+(defcustom php-default-face 'default
+  "Default face in `php-mode' buffers."
+  :type 'face
+  :group 'php)
+
+(defcustom php-speedbar-config t
+  "When set to true automatically configures Speedbar to observe PHP files.\
+Ignores php-file patterns option; fixed to expression \"\\.\\(inc\\|php[s34]?\\)\""
+  :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (if (and val (boundp 'speedbar))
+             (speedbar-add-supported-extension
+              "\\.\\(inc\\|php[s34]?\\|phtml\\)")))
+  :group 'php)
+
+(defcustom php-mode-speedbar-open nil
+  "Normally `php-mode' starts with the speedbar closed.\
+Turning this on will open it whenever `php-mode' is loaded."
+  :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (when val
+             (speedbar 1)))
+  :group 'php)
+
+(defcustom php-manual-url "http://www.php.net/manual/en/"
+  "URL at which to find PHP manual.\
+You can replace \"en\" with your ISO language code."
+  :type 'string
+  :group 'php)
+
+(defcustom php-search-url "http://www.php.net/"
+  "URL at which to search for documentation on a word"
+  :type 'string
+  :group 'php)
+
+(defcustom php-completion-file ""
+  "Path to the file which contains the function names known to PHP"
+  :type 'string
+  :group 'php)
+
+(defcustom php-manual-path ""
+  "Path to the directory which contains the PHP manual"
+  :type 'string
+  :group 'php)
+
+;;;###autoload
+(defcustom php-mode-to-use
+  (progn
+    (require 'mumamo nil t)
+    (if (fboundp 'nxhtml-mumamo-turn-on)
+        'nxhtml-mumamo-turn-on
+      (if (fboundp 'html-mumamo-turn-on)
+          'html-mumamo-turn-on
+        'php-mode)))
+  "Major mode turn on function to use for php files."
+  :type 'function
+  :group 'php)
+
+;;;###autoload
+(defcustom php-file-patterns '("\\.php[s34]?\\'" "\\.phtml\\'" "\\.inc\\'")
+  "List of file patterns for which to automatically invoke `php-mode'."
+  :type '(repeat (regexp :tag "Pattern"))
+  :set-after '(php-mode-to-use)
+  :set (lambda (sym val)
+         (set-default sym val)
+         (let ((php-file-patterns-temp val))
+           (while php-file-patterns-temp
+             (add-to-list 'auto-mode-alist
+                          (cons (car php-file-patterns-temp) php-mode-to-use))
+             (setq php-file-patterns-temp (cdr php-file-patterns-temp)))))
+  :group 'php)
+
+(defcustom php-mode-hook nil
+  "List of functions to be executed on entry to `php-mode'."
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-pear-hook nil
+  "Hook called when a PHP PEAR file is opened with `php-mode'."
+  :type 'hook
+  :group 'php)
+
+(defcustom php-mode-force-pear nil
+  "Normally PEAR coding rules are enforced only when the filename contains \"PEAR\"\
+Turning this on will force PEAR rules on all PHP files."
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-mode-dollar-property-warning nil
+  "If non-`nil', warn about expressions like $foo->$bar where you
+might have meant $foo->bar. Defaults to `nil' since this is valid
+code."
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-mode-dot-property-warning nil
+  "If non-`nil', wan about expressions like $foo.bar, which could
+be a valid concatenation (if bar were a constant, or interpreted
+as an unquoted string), but it's more likely you meant $foo->bar."
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-mode-warn-on-unmatched nil
+  "If non-`nil', use `font-lock-warning-face' on any expression
+that isn't matched by the other font lock regular expressions."
+  :type 'boolean
+  :group 'php)
+
+(defcustom php-warn-if-mumamo-off t
+  "Warn once per buffer if you try to indent a buffer without
+mumamo-mode turned on. Detects if there are any HTML tags in the
+buffer before warning, but this is not very smart; e.g. if you
+have any tags inside a PHP string, it will be fooled."
+  :type '(choice (const :tag "Warn" t) (const "Don't warn" nil))
+  :group 'php)
+
+
+(eval-when-compile
+  (defconst php-mode-modified
+    (save-excursion
+      (and
+       (re-search-backward "^;; Modified: \\(.*\\)" nil 'noerror)
+       (match-string-no-properties 1)))
+    "PHP Mode version number."))
+
+(defun php-mode-version ()
+  "Display string describing the version of PHP mode"
+  (interactive)
+  (message "PHP mode %s of %s"
+           php-mode-version-number php-mode-modified))
+
+(defconst php-beginning-of-defun-regexp
+  "^\\s *function\\s +&?\\(\\(\\sw\\|\\s_\\)+\\)\\s *("
+  "Regular expression for a PHP function.")
+
+(defun php-beginning-of-defun (&optional arg)
+  "Move to the beginning of the ARGth PHP function from point.
+Implements PHP version of `beginning-of-defun-function'."
+  (interactive "p")
+  (let ((arg (or arg 1)))
+    (while (> arg 0)
+      (re-search-backward php-beginning-of-defun-regexp
+                          nil 'noerror)
+      (setq arg (1- arg)))
+    (while (< arg 0)
+      (end-of-line 1)
+      (let ((opoint (point)))
+        (beginning-of-defun 1)
+        (forward-list 2)
+        (forward-line 1)
+        (if (eq opoint (point))
+            (re-search-forward php-beginning-of-defun-regexp
+                               nil 'noerror))
+	(setq arg (1+ arg))))))
+
+(defun php-end-of-defun (&optional arg)
+  "Move the end of the ARGth PHP function from point.
+Implements PHP befsion of `end-of-defun-function'
+
+See `php-beginning-of-defun'."
+  (interactive "p")
+  (php-beginning-of-defun (- (or arg 1))))
+
+
+(defvar php-completion-table nil
+  "Obarray of tag names defined in current tags table and functions know to PHP.")
+
+(defvar php-warned-bad-indent nil)
+;;(make-variable-buffer-local 'php-warned-bad-indent)
+
+;; Do it but tell it is not good if html tags in buffer.
+(defun php-check-html-for-indentation ()
+  (let ((html-tag-re "</?\\sw+.*?>")
+        (here (point)))
+    (if (not (or (re-search-forward html-tag-re (+ (point) 1000) t)
+                 (re-search-backward html-tag-re (- (point) 1000) t)))
+        t
+      (goto-char here)
+      (setq php-warned-bad-indent t)
+      ;;(setq php-warned-bad-indent nil)
+      (let* ((known-multi-libs '(("mumamo" mumamo (lambda () (nxhtml-mumamo)))
+                                 ("mmm-mode" mmm-mode (lambda () (mmm-mode 1)))
+                                 ("multi-mode" multi-mode (lambda () (multi-mode 1)))))
+             (known-names (mapcar (lambda (lib) (car lib)) known-multi-libs))
+             (available-multi-libs (delq nil
+                                         (mapcar
+                                          (lambda (lib)
+                                            (when (locate-library (car lib)) lib))
+                                          known-multi-libs)))
+             (available-names (mapcar (lambda (lib) (car lib)) available-multi-libs))
+             (base-msg
+              (concat
+               "Indentation fails badly with mixed HTML/PHP in plaín\n"
+               "`php-mode'.  To get indentation to work you must use an Emacs\n"
+               "library that supports 'multiple major modes' in a buffer.  Parts\n"
+               "of the buffer will then be in `php-mode' and parts in for example\n"
+               "`html-mode'.  Known such libraries are:\n\t"
+               (mapconcat 'identity known-names ", ")
+               "\n"
+               (if available-multi-libs
+                   (concat
+                    "You have these available in your `load-path':\n\t"
+                    (mapconcat 'identity available-names ", ")
+                    "\n\n"
+                    "Do you want to turn any of those on? ")
+                 "You do not have any of those in your `load-path'.")))
+             (is-using-multi
+              (catch 'is-using
+                (dolist (lib available-multi-libs)
+                  (when (and (boundp (cadr lib))
+                             (symbol-value (cadr lib)))
+                    (throw 'is-using t))))))
+        (unless is-using-multi
+          (if available-multi-libs
+              (if (not (y-or-n-p base-msg))
+                  (message "Did not do indentation, but you can try again now if you want")
+                (let* ((name
+                        (if (= 1 (length available-multi-libs))
+                            (car available-names)
+                          ;; Minibuffer window is more than one line, fix that first:
+                          (message "")
+                          (completing-read "Choose multiple major mode support library: "
+                                           available-names nil t
+                                           (car available-names)
+                                           '(available-names . 1)
+                                           )))
+                       (mode (when name
+                               (caddr (assoc name available-multi-libs)))))
+                  (when mode
+                    ;; Minibuffer window is more than one line, fix that first:
+                    (message "")
+                    (load name)
+                    (funcall mode))))
+            (lwarn 'php-indent :warning base-msg)))
+        nil))))
+
+(defun php-cautious-indent-region (start end &optional quiet)
+  (if (or (not php-warn-if-mumamo-off)
+          php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (funcall 'c-indent-region start end quiet)))
+
+(defun php-cautious-indent-line ()
+  (if (or (not php-warn-if-mumamo-off)
+          php-warned-bad-indent
+          (php-check-html-for-indentation))
+      (funcall 'c-indent-line)))
+
+;;;###autoload
+(define-derived-mode php-mode c-mode "PHP"
+  "Major mode for editing PHP code.\n\n\\{php-mode-map}"
+;;   (c-add-language 'php-mode 'c-mode)
+
+;;   (c-lang-defconst c-block-stmt-1-kwds
+;;     php php-block-stmt-1-kwds)
+  (set (make-local-variable 'c-block-stmt-1-key) php-block-stmt-1-key)
+
+;;   (c-lang-defconst c-block-stmt-2-kwds
+;;     php php-block-stmt-2-kwds)
+  (set (make-local-variable 'c-block-stmt-2-key) php-block-stmt-2-key)
+  ;; Specify that cc-mode recognize Javadoc comment style
+  (set (make-local-variable 'c-doc-comment-style)
+    '((php-mode . javadoc)))
+
+;;   (c-lang-defconst c-class-decl-kwds
+;;     php php-class-decl-kwds)
+  (set (make-local-variable 'c-class-key) php-class-key)
+
+  ;; this line makes $ into punctuation instead of a word constituent
+  ;; it used to be active, but it killed indenting of case lines that
+  ;; begin with '$' (many do).  If anyone has a solution to this
+  ;; problem, please let me know.  Of course, you're welcome to
+  ;; uncomment this line in your installation.
+;  (modify-syntax-entry ?$ "." php-mode-syntax-table)
+
+  ;; The above causes XEmacs to handle shell-style comments correctly,
+  ;; but fails to work in GNU Emacs which fails to interpret \n as the
+  ;; end of the comment.
+  (if (featurep 'xemacs) (progn
+                (modify-syntax-entry ?# "< b" php-mode-syntax-table)
+                (modify-syntax-entry ?\n "> b" php-mode-syntax-table)))
+
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults
+        '((php-font-lock-keywords-1
+           php-font-lock-keywords-2
+               ;; Comment-out the next line if the font-coloring is too
+               ;; extreme/ugly for you.
+           php-font-lock-keywords-3)
+          nil                               ; KEYWORDS-ONLY
+          nil                                 ; CASE-FOLD
+          nil                               ; SYNTAX-ALIST
+          nil))                             ; SYNTAX-BEGIN
+  (modify-syntax-entry ?# "< b" php-mode-syntax-table)
+  (modify-syntax-entry ?_ "w" php-mode-syntax-table)
+
+  ;; Electric behaviour must be turned off, they do not work since
+  ;; they can not find the correct syntax in embedded PHP.
+  ;;
+  ;; Seems to work with narrowing so let it be on if the user prefers it.
+  ;;(setq c-electric-flag nil)
+
+  (setq font-lock-maximum-decoration t
+        case-fold-search t              ; PHP vars are case-sensitive
+        imenu-generic-expression php-imenu-generic-expression)
+
+  ;; Do not force newline at end of file.  Such newlines can cause
+  ;; trouble if the PHP file is included in another file before calls
+  ;; to header() or cookie().
+  (set (make-local-variable 'require-final-newline) nil)
+  (set (make-local-variable 'next-line-add-newlines) nil)
+
+  ;; PEAR coding standards
+  (add-hook 'php-mode-pear-hook
+            (lambda ()
+              (set (make-local-variable 'tab-width) 4)
+              (set (make-local-variable 'c-basic-offset) 4)
+              (set (make-local-variable 'indent-tabs-mode) nil)
+              (c-set-offset 'block-open' - )
+              (c-set-offset 'block-close' 0 )) nil t)
+
+  (if (or php-mode-force-pear
+          (and (stringp buffer-file-name)
+               (string-match "PEAR\\|pear"
+                             (buffer-file-name))
+               (string-match "\\.php$" (buffer-file-name))))
+      (run-hooks 'php-mode-pear-hook))
+
+  (setq indent-line-function 'php-cautious-indent-line)
+  (setq indent-region-function 'php-cautious-indent-region)
+  (setq c-special-indent-hook nil)
+
+  (set (make-local-variable 'syntax-begin-function)
+       'c-beginning-of-syntax)
+  (set (make-local-variable 'beginning-of-defun-function)
+       'php-beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function)
+       'php-end-of-defun)
+  (set (make-local-variable 'open-paren-in-column-0-is-defun-start)
+       nil)
+  (set (make-local-variable 'defun-prompt-regexp)
+       "^\\s *function\\s +&?\\(\\(\\sw\\|\\s_\\)+\\)\\s *")
+  (set (make-local-variable 'add-log-current-defun-header-regexp)
+       php-beginning-of-defun-regexp)
+
+  (run-hooks 'php-mode-hook))
+
+;; Make a menu keymap (with a prompt string)
+;; and make it the menu bar item's definition.
+(define-key php-mode-map [menu-bar] (make-sparse-keymap))
+(define-key php-mode-map [menu-bar php]
+  (cons "PHP" (make-sparse-keymap "PHP")))
+
+;; Define specific subcommands in this menu.
+(define-key php-mode-map [menu-bar php complete-function]
+  '("Complete function name" . php-complete-function))
+(define-key php-mode-map
+  [menu-bar php browse-manual]
+  '("Browse manual" . php-browse-manual))
+(define-key php-mode-map
+  [menu-bar php search-documentation]
+  '("Search documentation" . php-search-documentation))
+
+;; Define function name completion function
+(defun php-complete-function ()
+  "Perform function completion on the text around point.
+Completes to the set of names listed in the current tags table
+and the standard php functions.
+The string to complete is chosen in the same way as the default
+for \\[find-tag] (which see)."
+  (interactive)
+  (let ((pattern (php-get-pattern))
+        beg
+        completion
+        (php-functions (php-completion-table)))
+    (if (not pattern) (message "Nothing to complete")
+        (search-backward pattern)
+        (setq beg (point))
+        (forward-char (length pattern))
+        (setq completion (try-completion pattern php-functions nil))
+        (cond ((eq completion t))
+              ((null completion)
+               (message "Can't find completion for \"%s\"" pattern)
+               (ding))
+              ((not (string= pattern completion))
+               (delete-region beg (point))
+               (insert completion))
+              (t
+               (message "Making completion list...")
+               (with-output-to-temp-buffer "*Completions*"
+                 (display-completion-list
+                  (all-completions pattern php-functions)))
+               (message "Making completion list...%s" "done"))))))
+
+;; Build php-completion-table on demand.  The table includes the
+;; PHP functions and the tags from the current tags-file-name
+(defun php-completion-table ()
+  (or (and tags-file-name
+           (save-excursion (tags-verify-table tags-file-name))
+           php-completion-table)
+      (let ((tags-table
+             (if (and tags-file-name
+                      (functionp 'etags-tags-completion-table))
+                 (with-current-buffer (get-file-buffer tags-file-name)
+                   (etags-tags-completion-table))
+               nil))
+            (php-table
+             (cond ((and (not (string= "" php-completion-file))
+                         (file-readable-p php-completion-file))
+                    (php-build-table-from-file php-completion-file))
+                   (php-manual-path
+                    (php-build-table-from-path php-manual-path))
+                   (t nil))))
+        (unless (or php-table tags-table)
+          (error
+           (concat "No TAGS file active nor are "
+                   "`php-completion-file' or `php-manual-path' set")))
+        (when tags-table
+          ;; Combine the tables.
+          (mapatoms (lambda (sym) (intern (symbol-name sym) php-table))
+                    tags-table))
+        (setq php-completion-table php-table))))
+
+(defun php-build-table-from-file (filename)
+  (let ((table (make-vector 1022 0))
+        (buf (find-file-noselect filename)))
+    (save-excursion
+      (set-buffer buf)
+      (goto-char (point-min))
+      (while (re-search-forward
+              "^\\([-a-zA-Z0-9_.]+\\)\n"
+              nil t)
+        (intern (buffer-substring (match-beginning 1) (match-end 1))
+                table)))
+    (kill-buffer buf)
+    table))
+
+(defun php-build-table-from-path (path)
+  (let ((table (make-vector 1022 0))
+        (files (directory-files
+                path
+                nil
+                "^function\\..+\\.html$")))
+    (mapc (lambda (file)
+            (string-match "\\.\\([-a-zA-Z_0-9]+\\)\\.html$" file)
+            (intern
+             (replace-regexp-in-string
+              "-" "_" (substring file (match-beginning 1) (match-end 1)) t)
+             table))
+          files)
+    table))
+
+;; Find the pattern we want to complete
+;; find-tag-default from GNU Emacs etags.el
+(defun php-get-pattern ()
+  (save-excursion
+    (while (looking-at "\\sw\\|\\s_")
+      (forward-char 1))
+    (if (or (re-search-backward "\\sw\\|\\s_"
+                                (save-excursion (beginning-of-line) (point))
+                                t)
+            (re-search-forward "\\(\\sw\\|\\s_\\)+"
+                               (save-excursion (end-of-line) (point))
+                               t))
+        (progn (goto-char (match-end 0))
+               (buffer-substring-no-properties
+                (point)
+                (progn (forward-sexp -1)
+                       (while (looking-at "\\s'")
+                         (forward-char 1))
+                       (point))))
+      nil)))
+
+
+(defun php-show-arglist ()
+  (interactive)
+  (let* ((tagname (php-get-pattern)) arglist)
+    (save-excursion
+      (set-buffer (find-tag-noselect tagname nil nil))
+      (goto-char (point-min))
+      (when (re-search-forward
+             (format "function[ \t]+%s[ \t]*(\\([^{]*\\))" tagname)
+             nil t)
+        (setq arglist (buffer-substring-no-properties
+                       (match-beginning 1) (match-end 1)))))
+    (if arglist
+        (message "Arglist for %s: %s" tagname arglist)
+      (message "Unknown function: %s" tagname))))
+
+;; Define function documentation function
+(defun php-search-documentation ()
+  "Search PHP documentation for the word at the point."
+  (interactive)
+  (browse-url (concat php-search-url (current-word t))))
+
+;; Define function for browsing manual
+(defun php-browse-manual ()
+  "Bring up manual for PHP."
+  (interactive)
+  (browse-url php-manual-url))
+
+;; Define shortcut
+(define-key php-mode-map
+  "\C-c\C-f"
+  'php-search-documentation)
+
+;; Define shortcut
+(define-key php-mode-map
+  [(meta tab)]
+  'php-complete-function)
+
+;; Define shortcut
+(define-key php-mode-map
+  "\C-c\C-m"
+  'php-browse-manual)
+
+;; Define shortcut
+(define-key php-mode-map
+  '[(control .)]
+  'php-show-arglist)
+
+(defconst php-constants
+  (eval-when-compile
+    (regexp-opt
+     '(;; core constants
+       "__LINE__" "__FILE__"
+       "__FUNCTION__" "__CLASS__" "__METHOD__"
+       "PHP_OS" "PHP_VERSION"
+       "TRUE" "FALSE" "NULL"
+       "E_ERROR" "E_NOTICE" "E_PARSE" "E_WARNING" "E_ALL" "E_STRICT"
+       "E_USER_ERROR" "E_USER_WARNING" "E_USER_NOTICE"
+       "DEFAULT_INCLUDE_PATH" "PEAR_INSTALL_DIR" "PEAR_EXTENSION_DIR"
+       "PHP_BINDIR" "PHP_LIBDIR" "PHP_DATADIR" "PHP_SYSCONFDIR"
+       "PHP_LOCALSTATEDIR" "PHP_CONFIG_FILE_PATH"
+       "PHP_EOL"
+
+       ;; from ext/standard:
+       "EXTR_OVERWRITE" "EXTR_SKIP" "EXTR_PREFIX_SAME"
+       "EXTR_PREFIX_ALL" "EXTR_PREFIX_INVALID" "SORT_ASC" "SORT_DESC"
+       "SORT_REGULAR" "SORT_NUMERIC" "SORT_STRING" "ASSERT_ACTIVE"
+       "ASSERT_CALLBACK" "ASSERT_BAIL" "ASSERT_WARNING"
+       "ASSERT_QUIET_EVAL" "CONNECTION_ABORTED" "CONNECTION_NORMAL"
+       "CONNECTION_TIMEOUT" "M_E" "M_LOG2E" "M_LOG10E" "M_LN2"
+       "M_LN10" "M_PI" "M_PI_2" "M_PI_4" "M_1_PI" "M_2_PI"
+       "M_2_SQRTPI" "M_SQRT2" "M_SQRT1_2" "CRYPT_SALT_LENGTH"
+       "CRYPT_STD_DES" "CRYPT_EXT_DES" "CRYPT_MD5" "CRYPT_BLOWFISH"
+       "DIRECTORY_SEPARATOR" "SEEK_SET" "SEEK_CUR" "SEEK_END"
+       "LOCK_SH" "LOCK_EX" "LOCK_UN" "LOCK_NB" "HTML_SPECIALCHARS"
+       "HTML_ENTITIES" "ENT_COMPAT" "ENT_QUOTES" "ENT_NOQUOTES"
+       "INFO_GENERAL" "INFO_CREDITS" "INFO_CONFIGURATION"
+       "INFO_ENVIRONMENT" "INFO_VARIABLES" "INFO_LICENSE" "INFO_ALL"
+       "CREDITS_GROUP" "CREDITS_GENERAL" "CREDITS_SAPI"
+       "CREDITS_MODULES" "CREDITS_DOCS" "CREDITS_FULLPAGE"
+       "CREDITS_QA" "CREDITS_ALL" "PHP_OUTPUT_HANDLER_START"
+       "PHP_OUTPUT_HANDLER_CONT" "PHP_OUTPUT_HANDLER_END"
+       "STR_PAD_LEFT" "STR_PAD_RIGHT" "STR_PAD_BOTH"
+       "PATHINFO_DIRNAME" "PATHINFO_BASENAME" "PATHINFO_EXTENSION"
+       "CHAR_MAX" "LC_CTYPE" "LC_NUMERIC" "LC_TIME" "LC_COLLATE"
+       "LC_MONETARY" "LC_ALL" "LC_MESSAGES" "LOG_EMERG" "LOG_ALERT"
+       "LOG_CRIT" "LOG_ERR" "LOG_WARNING" "LOG_NOTICE" "LOG_INFO"
+       "LOG_DEBUG" "LOG_KERN" "LOG_USER" "LOG_MAIL" "LOG_DAEMON"
+       "LOG_AUTH" "LOG_SYSLOG" "LOG_LPR" "LOG_NEWS" "LOG_UUCP"
+       "LOG_CRON" "LOG_AUTHPRIV" "LOG_LOCAL0" "LOG_LOCAL1"
+       "LOG_LOCAL2" "LOG_LOCAL3" "LOG_LOCAL4" "LOG_LOCAL5"
+       "LOG_LOCAL6" "LOG_LOCAL7" "LOG_PID" "LOG_CONS" "LOG_ODELAY"
+       "LOG_NDELAY" "LOG_NOWAIT" "LOG_PERROR"
+
+       ;; Disabled by default because they slow buffer loading
+       ;; If you have use for them, uncomment the strings
+       ;; that you want colored.
+       ;; To compile, you may have to increase 'max-specpdl-size'
+
+       ;; from other bundled extensions:
+;        "CAL_EASTER_TO_xxx" "VT_NULL" "VT_EMPTY" "VT_UI1" "VT_I2"
+;        "VT_I4" "VT_R4" "VT_R8" "VT_BOOL" "VT_ERROR" "VT_CY" "VT_DATE"
+;        "VT_BSTR" "VT_DECIMAL" "VT_UNKNOWN" "VT_DISPATCH" "VT_VARIANT"
+;        "VT_I1" "VT_UI2" "VT_UI4" "VT_INT" "VT_UINT" "VT_ARRAY"
+;        "VT_BYREF" "CP_ACP" "CP_MACCP" "CP_OEMCP" "CP_SYMBOL"
+;        "CP_THREAD_ACP" "CP_UTF7" "CP_UTF8" "CPDF_PM_NONE"
+;        "CPDF_PM_OUTLINES" "CPDF_PM_THUMBS" "CPDF_PM_FULLSCREEN"
+;        "CPDF_PL_SINGLE" "CPDF_PL_1COLUMN" "CPDF_PL_2LCOLUMN"
+;        "CPDF_PL_2RCOLUMN" "CURLOPT_PORT" "CURLOPT_FILE"
+;        "CURLOPT_INFILE" "CURLOPT_INFILESIZE" "CURLOPT_URL"
+;        "CURLOPT_PROXY" "CURLOPT_VERBOSE" "CURLOPT_HEADER"
+;        "CURLOPT_HTTPHEADER" "CURLOPT_NOPROGRESS" "CURLOPT_NOBODY"
+;        "CURLOPT_FAILONERROR" "CURLOPT_UPLOAD" "CURLOPT_POST"
+;        "CURLOPT_FTPLISTONLY" "CURLOPT_FTPAPPEND" "CURLOPT_NETRC"
+;        "CURLOPT_FOLLOWLOCATION" "CURLOPT_FTPASCII" "CURLOPT_PUT"
+;        "CURLOPT_MUTE" "CURLOPT_USERPWD" "CURLOPT_PROXYUSERPWD"
+;        "CURLOPT_RANGE" "CURLOPT_TIMEOUT" "CURLOPT_POSTFIELDS"
+;        "CURLOPT_REFERER" "CURLOPT_USERAGENT" "CURLOPT_FTPPORT"
+;        "CURLOPT_LOW_SPEED_LIMIT" "CURLOPT_LOW_SPEED_TIME"
+;        "CURLOPT_RESUME_FROM" "CURLOPT_COOKIE" "CURLOPT_SSLCERT"
+;        "CURLOPT_SSLCERTPASSWD" "CURLOPT_WRITEHEADER"
+;        "CURLOPT_COOKIEFILE" "CURLOPT_SSLVERSION"
+;        "CURLOPT_TIMECONDITION" "CURLOPT_TIMEVALUE"
+;        "CURLOPT_CUSTOMREQUEST" "CURLOPT_STDERR" "CURLOPT_TRANSFERTEXT"
+;        "CURLOPT_RETURNTRANSFER" "CURLOPT_QUOTE" "CURLOPT_POSTQUOTE"
+;        "CURLOPT_INTERFACE" "CURLOPT_KRB4LEVEL"
+;        "CURLOPT_HTTPPROXYTUNNEL" "CURLOPT_FILETIME"
+;        "CURLOPT_WRITEFUNCTION" "CURLOPT_READFUNCTION"
+;        "CURLOPT_PASSWDFUNCTION" "CURLOPT_HEADERFUNCTION"
+;        "CURLOPT_MAXREDIRS" "CURLOPT_MAXCONNECTS" "CURLOPT_CLOSEPOLICY"
+;        "CURLOPT_FRESH_CONNECT" "CURLOPT_FORBID_REUSE"
+;        "CURLOPT_RANDOM_FILE" "CURLOPT_EGDSOCKET"
+;        "CURLOPT_CONNECTTIMEOUT" "CURLOPT_SSL_VERIFYPEER"
+;        "CURLOPT_CAINFO" "CURLOPT_BINARYTRANSER"
+;        "CURLCLOSEPOLICY_LEAST_RECENTLY_USED" "CURLCLOSEPOLICY_OLDEST"
+;        "CURLINFO_EFFECTIVE_URL" "CURLINFO_HTTP_CODE"
+;        "CURLINFO_HEADER_SIZE" "CURLINFO_REQUEST_SIZE"
+;        "CURLINFO_TOTAL_TIME" "CURLINFO_NAMELOOKUP_TIME"
+;        "CURLINFO_CONNECT_TIME" "CURLINFO_PRETRANSFER_TIME"
+;        "CURLINFO_SIZE_UPLOAD" "CURLINFO_SIZE_DOWNLOAD"
+;        "CURLINFO_SPEED_DOWNLOAD" "CURLINFO_SPEED_UPLOAD"
+;        "CURLINFO_FILETIME" "CURLE_OK" "CURLE_UNSUPPORTED_PROTOCOL"
+;        "CURLE_FAILED_INIT" "CURLE_URL_MALFORMAT"
+;        "CURLE_URL_MALFORMAT_USER" "CURLE_COULDNT_RESOLVE_PROXY"
+;        "CURLE_COULDNT_RESOLVE_HOST" "CURLE_COULDNT_CONNECT"
+;        "CURLE_FTP_WEIRD_SERVER_REPLY" "CURLE_FTP_ACCESS_DENIED"
+;        "CURLE_FTP_USER_PASSWORD_INCORRECT"
+;        "CURLE_FTP_WEIRD_PASS_REPLY" "CURLE_FTP_WEIRD_USER_REPLY"
+;        "CURLE_FTP_WEIRD_PASV_REPLY" "CURLE_FTP_WEIRD_227_FORMAT"
+;        "CURLE_FTP_CANT_GET_HOST" "CURLE_FTP_CANT_RECONNECT"
+;        "CURLE_FTP_COULDNT_SET_BINARY" "CURLE_PARTIAL_FILE"
+;        "CURLE_FTP_COULDNT_RETR_FILE" "CURLE_FTP_WRITE_ERROR"
+;        "CURLE_FTP_QUOTE_ERROR" "CURLE_HTTP_NOT_FOUND"
+;        "CURLE_WRITE_ERROR" "CURLE_MALFORMAT_USER"
+;        "CURLE_FTP_COULDNT_STOR_FILE" "CURLE_READ_ERROR"
+;        "CURLE_OUT_OF_MEMORY" "CURLE_OPERATION_TIMEOUTED"
+;        "CURLE_FTP_COULDNT_SET_ASCII" "CURLE_FTP_PORT_FAILED"
+;        "CURLE_FTP_COULDNT_USE_REST" "CURLE_FTP_COULDNT_GET_SIZE"
+;        "CURLE_HTTP_RANGE_ERROR" "CURLE_HTTP_POST_ERROR"
+;        "CURLE_SSL_CONNECT_ERROR" "CURLE_FTP_BAD_DOWNLOAD_RESUME"
+;        "CURLE_FILE_COULDNT_READ_FILE" "CURLE_LDAP_CANNOT_BIND"
+;        "CURLE_LDAP_SEARCH_FAILED" "CURLE_LIBRARY_NOT_FOUND"
+;        "CURLE_FUNCTION_NOT_FOUND" "CURLE_ABORTED_BY_CALLBACK"
+;        "CURLE_BAD_FUNCTION_ARGUMENT" "CURLE_BAD_CALLING_ORDER"
+;        "CURLE_HTTP_PORT_FAILED" "CURLE_BAD_PASSWORD_ENTERED"
+;        "CURLE_TOO_MANY_REDIRECTS" "CURLE_UNKOWN_TELNET_OPTION"
+;        "CURLE_TELNET_OPTION_SYNTAX" "CURLE_ALREADY_COMPLETE"
+;        "DBX_MYSQL" "DBX_ODBC" "DBX_PGSQL" "DBX_MSSQL" "DBX_PERSISTENT"
+;        "DBX_RESULT_INFO" "DBX_RESULT_INDEX" "DBX_RESULT_ASSOC"
+;        "DBX_CMP_TEXT" "DBX_CMP_NUMBER" "XML_ELEMENT_NODE"
+;        "XML_ATTRIBUTE_NODE" "XML_TEXT_NODE" "XML_CDATA_SECTION_NODE"
+;        "XML_ENTITY_REF_NODE" "XML_ENTITY_NODE" "XML_PI_NODE"
+;        "XML_COMMENT_NODE" "XML_DOCUMENT_NODE" "XML_DOCUMENT_TYPE_NODE"
+;        "XML_DOCUMENT_FRAG_NODE" "XML_NOTATION_NODE"
+;        "XML_HTML_DOCUMENT_NODE" "XML_DTD_NODE" "XML_ELEMENT_DECL_NODE"
+;        "XML_ATTRIBUTE_DECL_NODE" "XML_ENTITY_DECL_NODE"
+;        "XML_NAMESPACE_DECL_NODE" "XML_GLOBAL_NAMESPACE"
+;        "XML_LOCAL_NAMESPACE" "XML_ATTRIBUTE_CDATA" "XML_ATTRIBUTE_ID"
+;        "XML_ATTRIBUTE_IDREF" "XML_ATTRIBUTE_IDREFS"
+;        "XML_ATTRIBUTE_ENTITY" "XML_ATTRIBUTE_NMTOKEN"
+;        "XML_ATTRIBUTE_NMTOKENS" "XML_ATTRIBUTE_ENUMERATION"
+;        "XML_ATTRIBUTE_NOTATION" "XPATH_UNDEFINED" "XPATH_NODESET"
+;        "XPATH_BOOLEAN" "XPATH_NUMBER" "XPATH_STRING" "XPATH_POINT"
+;        "XPATH_RANGE" "XPATH_LOCATIONSET" "XPATH_USERS" "FBSQL_ASSOC"
+;        "FBSQL_NUM" "FBSQL_BOTH" "FDFValue" "FDFStatus" "FDFFile"
+;        "FDFID" "FDFFf" "FDFSetFf" "FDFClearFf" "FDFFlags" "FDFSetF"
+;        "FDFClrF" "FDFAP" "FDFAS" "FDFAction" "FDFAA" "FDFAPRef"
+;        "FDFIF" "FDFEnter" "FDFExit" "FDFDown" "FDFUp" "FDFFormat"
+;        "FDFValidate" "FDFKeystroke" "FDFCalculate"
+;        "FRIBIDI_CHARSET_UTF8" "FRIBIDI_CHARSET_8859_6"
+;        "FRIBIDI_CHARSET_8859_8" "FRIBIDI_CHARSET_CP1255"
+;        "FRIBIDI_CHARSET_CP1256" "FRIBIDI_CHARSET_ISIRI_3342"
+;        "FTP_ASCII" "FTP_BINARY" "FTP_IMAGE" "FTP_TEXT" "IMG_GIF"
+;        "IMG_JPG" "IMG_JPEG" "IMG_PNG" "IMG_WBMP" "IMG_COLOR_TILED"
+;        "IMG_COLOR_STYLED" "IMG_COLOR_BRUSHED"
+;        "IMG_COLOR_STYLEDBRUSHED" "IMG_COLOR_TRANSPARENT"
+;        "IMG_ARC_ROUNDED" "IMG_ARC_PIE" "IMG_ARC_CHORD"
+;        "IMG_ARC_NOFILL" "IMG_ARC_EDGED" "GMP_ROUND_ZERO"
+;        "GMP_ROUND_PLUSINF" "GMP_ROUND_MINUSINF" "HW_ATTR_LANG"
+;        "HW_ATTR_NR" "HW_ATTR_NONE" "IIS_READ" "IIS_WRITE"
+;        "IIS_EXECUTE" "IIS_SCRIPT" "IIS_ANONYMOUS" "IIS_BASIC"
+;        "IIS_NTLM" "NIL" "OP_DEBUG" "OP_READONLY" "OP_ANONYMOUS"
+;        "OP_SHORTCACHE" "OP_SILENT" "OP_PROTOTYPE" "OP_HALFOPEN"
+;        "OP_EXPUNGE" "OP_SECURE" "CL_EXPUNGE" "FT_UID" "FT_PEEK"
+;        "FT_NOT" "FT_INTERNAL" "FT_PREFETCHTEXT" "ST_UID" "ST_SILENT"
+;        "ST_SET" "CP_UID" "CP_MOVE" "SE_UID" "SE_FREE" "SE_NOPREFETCH"
+;        "SO_FREE" "SO_NOSERVER" "SA_MESSAGES" "SA_RECENT" "SA_UNSEEN"
+;        "SA_UIDNEXT" "SA_UIDVALIDITY" "SA_ALL" "LATT_NOINFERIORS"
+;        "LATT_NOSELECT" "LATT_MARKED" "LATT_UNMARKED" "SORTDATE"
+;        "SORTARRIVAL" "SORTFROM" "SORTSUBJECT" "SORTTO" "SORTCC"
+;        "SORTSIZE" "TYPETEXT" "TYPEMULTIPART" "TYPEMESSAGE"
+;        "TYPEAPPLICATION" "TYPEAUDIO" "TYPEIMAGE" "TYPEVIDEO"
+;        "TYPEOTHER" "ENC7BIT" "ENC8BIT" "ENCBINARY" "ENCBASE64"
+;        "ENCQUOTEDPRINTABLE" "ENCOTHER" "INGRES_ASSOC" "INGRES_NUM"
+;        "INGRES_BOTH" "IBASE_DEFAULT" "IBASE_TEXT" "IBASE_UNIXTIME"
+;        "IBASE_READ" "IBASE_COMMITTED" "IBASE_CONSISTENCY"
+;        "IBASE_NOWAIT" "IBASE_TIMESTAMP" "IBASE_DATE" "IBASE_TIME"
+;        "LDAP_DEREF_NEVER" "LDAP_DEREF_SEARCHING" "LDAP_DEREF_FINDING"
+;        "LDAP_DEREF_ALWAYS" "LDAP_OPT_DEREF" "LDAP_OPT_SIZELIMIT"
+;        "LDAP_OPT_TIMELIMIT" "LDAP_OPT_PROTOCOL_VERSION"
+;        "LDAP_OPT_ERROR_NUMBER" "LDAP_OPT_REFERRALS" "LDAP_OPT_RESTART"
+;        "LDAP_OPT_HOST_NAME" "LDAP_OPT_ERROR_STRING"
+;        "LDAP_OPT_MATCHED_DN" "LDAP_OPT_SERVER_CONTROLS"
+;        "LDAP_OPT_CLIENT_CONTROLS" "GSLC_SSL_NO_AUTH"
+;        "GSLC_SSL_ONEWAY_AUTH" "GSLC_SSL_TWOWAY_AUTH" "MCAL_SUNDAY"
+;        "MCAL_MONDAY" "MCAL_TUESDAY" "MCAL_WEDNESDAY" "MCAL_THURSDAY"
+;        "MCAL_FRIDAY" "MCAL_SATURDAY" "MCAL_JANUARY" "MCAL_FEBRUARY"
+;        "MCAL_MARCH" "MCAL_APRIL" "MCAL_MAY" "MCAL_JUNE" "MCAL_JULY"
+;        "MCAL_AUGUST" "MCAL_SEPTEMBER" "MCAL_OCTOBER" "MCAL_NOVEMBER"
+;        "MCAL_RECUR_NONE" "MCAL_RECUR_DAILY" "MCAL_RECUR_WEEKLY"
+;        "MCAL_RECUR_MONTHLY_MDAY" "MCAL_RECUR_MONTHLY_WDAY"
+;        "MCAL_RECUR_YEARLY" "MCAL_M_SUNDAY" "MCAL_M_MONDAY"
+;        "MCAL_M_TUESDAY" "MCAL_M_WEDNESDAY" "MCAL_M_THURSDAY"
+;        "MCAL_M_FRIDAY" "MCAL_M_SATURDAY" "MCAL_M_WEEKDAYS"
+;        "MCAL_M_WEEKEND" "MCAL_M_ALLDAYS" "MCRYPT_" "MCRYPT_"
+;        "MCRYPT_ENCRYPT" "MCRYPT_DECRYPT" "MCRYPT_DEV_RANDOM"
+;        "MCRYPT_DEV_URANDOM" "MCRYPT_RAND" "SWFBUTTON_HIT"
+;        "SWFBUTTON_DOWN" "SWFBUTTON_OVER" "SWFBUTTON_UP"
+;        "SWFBUTTON_MOUSEUPOUTSIDE" "SWFBUTTON_DRAGOVER"
+;        "SWFBUTTON_DRAGOUT" "SWFBUTTON_MOUSEUP" "SWFBUTTON_MOUSEDOWN"
+;        "SWFBUTTON_MOUSEOUT" "SWFBUTTON_MOUSEOVER"
+;        "SWFFILL_RADIAL_GRADIENT" "SWFFILL_LINEAR_GRADIENT"
+;        "SWFFILL_TILED_BITMAP" "SWFFILL_CLIPPED_BITMAP"
+;        "SWFTEXTFIELD_HASLENGTH" "SWFTEXTFIELD_NOEDIT"
+;        "SWFTEXTFIELD_PASSWORD" "SWFTEXTFIELD_MULTILINE"
+;        "SWFTEXTFIELD_WORDWRAP" "SWFTEXTFIELD_DRAWBOX"
+;        "SWFTEXTFIELD_NOSELECT" "SWFTEXTFIELD_HTML"
+;        "SWFTEXTFIELD_ALIGN_LEFT" "SWFTEXTFIELD_ALIGN_RIGHT"
+;        "SWFTEXTFIELD_ALIGN_CENTER" "SWFTEXTFIELD_ALIGN_JUSTIFY"
+;        "UDM_FIELD_URLID" "UDM_FIELD_URL" "UDM_FIELD_CONTENT"
+;        "UDM_FIELD_TITLE" "UDM_FIELD_KEYWORDS" "UDM_FIELD_DESC"
+;        "UDM_FIELD_DESCRIPTION" "UDM_FIELD_TEXT" "UDM_FIELD_SIZE"
+;        "UDM_FIELD_RATING" "UDM_FIELD_SCORE" "UDM_FIELD_MODIFIED"
+;        "UDM_FIELD_ORDER" "UDM_FIELD_CRC" "UDM_FIELD_CATEGORY"
+;        "UDM_PARAM_PAGE_SIZE" "UDM_PARAM_PAGE_NUM"
+;        "UDM_PARAM_SEARCH_MODE" "UDM_PARAM_CACHE_MODE"
+;        "UDM_PARAM_TRACK_MODE" "UDM_PARAM_PHRASE_MODE"
+;        "UDM_PARAM_CHARSET" "UDM_PARAM_STOPTABLE"
+;        "UDM_PARAM_STOP_TABLE" "UDM_PARAM_STOPFILE"
+;        "UDM_PARAM_STOP_FILE" "UDM_PARAM_WEIGHT_FACTOR"
+;        "UDM_PARAM_WORD_MATCH" "UDM_PARAM_MAX_WORD_LEN"
+;        "UDM_PARAM_MAX_WORDLEN" "UDM_PARAM_MIN_WORD_LEN"
+;        "UDM_PARAM_MIN_WORDLEN" "UDM_PARAM_ISPELL_PREFIXES"
+;        "UDM_PARAM_ISPELL_PREFIX" "UDM_PARAM_PREFIXES"
+;        "UDM_PARAM_PREFIX" "UDM_PARAM_CROSS_WORDS"
+;        "UDM_PARAM_CROSSWORDS" "UDM_LIMIT_CAT" "UDM_LIMIT_URL"
+;        "UDM_LIMIT_TAG" "UDM_LIMIT_LANG" "UDM_LIMIT_DATE"
+;        "UDM_PARAM_FOUND" "UDM_PARAM_NUM_ROWS" "UDM_PARAM_WORDINFO"
+;        "UDM_PARAM_WORD_INFO" "UDM_PARAM_SEARCHTIME"
+;        "UDM_PARAM_SEARCH_TIME" "UDM_PARAM_FIRST_DOC"
+;        "UDM_PARAM_LAST_DOC" "UDM_MODE_ALL" "UDM_MODE_ANY"
+;        "UDM_MODE_BOOL" "UDM_MODE_PHRASE" "UDM_CACHE_ENABLED"
+;        "UDM_CACHE_DISABLED" "UDM_TRACK_ENABLED" "UDM_TRACK_DISABLED"
+;        "UDM_PHRASE_ENABLED" "UDM_PHRASE_DISABLED"
+;        "UDM_CROSS_WORDS_ENABLED" "UDM_CROSSWORDS_ENABLED"
+;        "UDM_CROSS_WORDS_DISABLED" "UDM_CROSSWORDS_DISABLED"
+;        "UDM_PREFIXES_ENABLED" "UDM_PREFIX_ENABLED"
+;        "UDM_ISPELL_PREFIXES_ENABLED" "UDM_ISPELL_PREFIX_ENABLED"
+;        "UDM_PREFIXES_DISABLED" "UDM_PREFIX_DISABLED"
+;        "UDM_ISPELL_PREFIXES_DISABLED" "UDM_ISPELL_PREFIX_DISABLED"
+;        "UDM_ISPELL_TYPE_AFFIX" "UDM_ISPELL_TYPE_SPELL"
+;        "UDM_ISPELL_TYPE_DB" "UDM_ISPELL_TYPE_SERVER" "UDM_MATCH_WORD"
+;        "UDM_MATCH_BEGIN" "UDM_MATCH_SUBSTR" "UDM_MATCH_END"
+;        "MSQL_ASSOC" "MSQL_NUM" "MSQL_BOTH" "MYSQL_ASSOC" "MYSQL_NUM"
+;        "MYSQL_BOTH" "MYSQL_USE_RESULT" "MYSQL_STORE_RESULT"
+;        "OCI_DEFAULT" "OCI_DESCRIBE_ONLY" "OCI_COMMIT_ON_SUCCESS"
+;        "OCI_EXACT_FETCH" "SQLT_BFILEE" "SQLT_CFILEE" "SQLT_CLOB"
+;        "SQLT_BLOB" "SQLT_RDD" "OCI_B_SQLT_NTY" "OCI_SYSDATE"
+;        "OCI_B_BFILE" "OCI_B_CFILEE" "OCI_B_CLOB" "OCI_B_BLOB"
+;        "OCI_B_ROWID" "OCI_B_CURSOR" "OCI_B_BIN" "OCI_ASSOC" "OCI_NUM"
+;        "OCI_BOTH" "OCI_RETURN_NULLS" "OCI_RETURN_LOBS"
+;        "OCI_DTYPE_FILE" "OCI_DTYPE_LOB" "OCI_DTYPE_ROWID" "OCI_D_FILE"
+;        "OCI_D_LOB" "OCI_D_ROWID" "ODBC_TYPE" "ODBC_BINMODE_PASSTHRU"
+;        "ODBC_BINMODE_RETURN" "ODBC_BINMODE_CONVERT" "SQL_ODBC_CURSORS"
+;        "SQL_CUR_USE_DRIVER" "SQL_CUR_USE_IF_NEEDED" "SQL_CUR_USE_ODBC"
+;        "SQL_CONCURRENCY" "SQL_CONCUR_READ_ONLY" "SQL_CONCUR_LOCK"
+;        "SQL_CONCUR_ROWVER" "SQL_CONCUR_VALUES" "SQL_CURSOR_TYPE"
+;        "SQL_CURSOR_FORWARD_ONLY" "SQL_CURSOR_KEYSET_DRIVEN"
+;        "SQL_CURSOR_DYNAMIC" "SQL_CURSOR_STATIC" "SQL_KEYSET_SIZE"
+;        "SQL_CHAR" "SQL_VARCHAR" "SQL_LONGVARCHAR" "SQL_DECIMAL"
+;        "SQL_NUMERIC" "SQL_BIT" "SQL_TINYINT" "SQL_SMALLINT"
+;        "SQL_INTEGER" "SQL_BIGINT" "SQL_REAL" "SQL_FLOAT" "SQL_DOUBLE"
+;        "SQL_BINARY" "SQL_VARBINARY" "SQL_LONGVARBINARY" "SQL_DATE"
+;        "SQL_TIME" "SQL_TIMESTAMP" "SQL_TYPE_DATE" "SQL_TYPE_TIME"
+;        "SQL_TYPE_TIMESTAMP" "SQL_BEST_ROWID" "SQL_ROWVER"
+;        "SQL_SCOPE_CURROW" "SQL_SCOPE_TRANSACTION" "SQL_SCOPE_SESSION"
+;        "SQL_NO_NULLS" "SQL_NULLABLE" "SQL_INDEX_UNIQUE"
+;        "SQL_INDEX_ALL" "SQL_ENSURE" "SQL_QUICK"
+;        "X509_PURPOSE_SSL_CLIENT" "X509_PURPOSE_SSL_SERVER"
+;        "X509_PURPOSE_NS_SSL_SERVER" "X509_PURPOSE_SMIME_SIGN"
+;        "X509_PURPOSE_SMIME_ENCRYPT" "X509_PURPOSE_CRL_SIGN"
+;        "X509_PURPOSE_ANY" "PKCS7_DETACHED" "PKCS7_TEXT"
+;        "PKCS7_NOINTERN" "PKCS7_NOVERIFY" "PKCS7_NOCHAIN"
+;        "PKCS7_NOCERTS" "PKCS7_NOATTR" "PKCS7_BINARY" "PKCS7_NOSIGS"
+;        "OPENSSL_PKCS1_PADDING" "OPENSSL_SSLV23_PADDING"
+;        "OPENSSL_NO_PADDING" "OPENSSL_PKCS1_OAEP_PADDING"
+;        "ORA_BIND_INOUT" "ORA_BIND_IN" "ORA_BIND_OUT"
+;        "ORA_FETCHINTO_ASSOC" "ORA_FETCHINTO_NULLS"
+;        "PREG_PATTERN_ORDER" "PREG_SET_ORDER" "PREG_SPLIT_NO_EMPTY"
+;        "PREG_SPLIT_DELIM_CAPTURE"
+;        "PGSQL_ASSOC" "PGSQL_NUM" "PGSQL_BOTH"
+;        "PRINTER_COPIES" "PRINTER_MODE" "PRINTER_TITLE"
+;        "PRINTER_DEVICENAME" "PRINTER_DRIVERVERSION"
+;        "PRINTER_RESOLUTION_Y" "PRINTER_RESOLUTION_X" "PRINTER_SCALE"
+;        "PRINTER_BACKGROUND_COLOR" "PRINTER_PAPER_LENGTH"
+;        "PRINTER_PAPER_WIDTH" "PRINTER_PAPER_FORMAT"
+;        "PRINTER_FORMAT_CUSTOM" "PRINTER_FORMAT_LETTER"
+;        "PRINTER_FORMAT_LEGAL" "PRINTER_FORMAT_A3" "PRINTER_FORMAT_A4"
+;        "PRINTER_FORMAT_A5" "PRINTER_FORMAT_B4" "PRINTER_FORMAT_B5"
+;        "PRINTER_FORMAT_FOLIO" "PRINTER_ORIENTATION"
+;        "PRINTER_ORIENTATION_PORTRAIT" "PRINTER_ORIENTATION_LANDSCAPE"
+;        "PRINTER_TEXT_COLOR" "PRINTER_TEXT_ALIGN" "PRINTER_TA_BASELINE"
+;        "PRINTER_TA_BOTTOM" "PRINTER_TA_TOP" "PRINTER_TA_CENTER"
+;        "PRINTER_TA_LEFT" "PRINTER_TA_RIGHT" "PRINTER_PEN_SOLID"
+;        "PRINTER_PEN_DASH" "PRINTER_PEN_DOT" "PRINTER_PEN_DASHDOT"
+;        "PRINTER_PEN_DASHDOTDOT" "PRINTER_PEN_INVISIBLE"
+;        "PRINTER_BRUSH_SOLID" "PRINTER_BRUSH_CUSTOM"
+;        "PRINTER_BRUSH_DIAGONAL" "PRINTER_BRUSH_CROSS"
+;        "PRINTER_BRUSH_DIAGCROSS" "PRINTER_BRUSH_FDIAGONAL"
+;        "PRINTER_BRUSH_HORIZONTAL" "PRINTER_BRUSH_VERTICAL"
+;        "PRINTER_FW_THIN" "PRINTER_FW_ULTRALIGHT" "PRINTER_FW_LIGHT"
+;        "PRINTER_FW_NORMAL" "PRINTER_FW_MEDIUM" "PRINTER_FW_BOLD"
+;        "PRINTER_FW_ULTRABOLD" "PRINTER_FW_HEAVY" "PRINTER_ENUM_LOCAL"
+;        "PRINTER_ENUM_NAME" "PRINTER_ENUM_SHARED"
+;        "PRINTER_ENUM_DEFAULT" "PRINTER_ENUM_CONNECTIONS"
+;        "PRINTER_ENUM_NETWORK" "PRINTER_ENUM_REMOTE" "PSPELL_FAST"
+;        "PSPELL_NORMAL" "PSPELL_BAD_SPELLERS" "PSPELL_RUN_TOGETHER"
+;        "SID" "SID" "AF_UNIX" "AF_INET" "SOCK_STREAM" "SOCK_DGRAM"
+;        "SOCK_RAW" "SOCK_SEQPACKET" "SOCK_RDM" "MSG_OOB" "MSG_WAITALL"
+;        "MSG_PEEK" "MSG_DONTROUTE" "SO_DEBUG" "SO_REUSEADDR"
+;        "SO_KEEPALIVE" "SO_DONTROUTE" "SO_LINGER" "SO_BROADCAST"
+;        "SO_OOBINLINE" "SO_SNDBUF" "SO_RCVBUF" "SO_SNDLOWAT"
+;        "SO_RCVLOWAT" "SO_SNDTIMEO" "SO_RCVTIMEO" "SO_TYPE" "SO_ERROR"
+;        "SOL_SOCKET" "PHP_NORMAL_READ" "PHP_BINARY_READ"
+;        "PHP_SYSTEM_READ" "SOL_TCP" "SOL_UDP" "MOD_COLOR" "MOD_MATRIX"
+;        "TYPE_PUSHBUTTON" "TYPE_MENUBUTTON" "BSHitTest" "BSDown"
+;        "BSOver" "BSUp" "OverDowntoIdle" "IdletoOverDown"
+;        "OutDowntoIdle" "OutDowntoOverDown" "OverDowntoOutDown"
+;        "OverUptoOverDown" "OverUptoIdle" "IdletoOverUp" "ButtonEnter"
+;        "ButtonExit" "MenuEnter" "MenuExit" "XML_ERROR_NONE"
+;        "XML_ERROR_NO_MEMORY" "XML_ERROR_SYNTAX"
+;        "XML_ERROR_NO_ELEMENTS" "XML_ERROR_INVALID_TOKEN"
+;        "XML_ERROR_UNCLOSED_TOKEN" "XML_ERROR_PARTIAL_CHAR"
+;        "XML_ERROR_TAG_MISMATCH" "XML_ERROR_DUPLICATE_ATTRIBUTE"
+;        "XML_ERROR_JUNK_AFTER_DOC_ELEMENT" "XML_ERROR_PARAM_ENTITY_REF"
+;        "XML_ERROR_UNDEFINED_ENTITY" "XML_ERROR_RECURSIVE_ENTITY_REF"
+;        "XML_ERROR_ASYNC_ENTITY" "XML_ERROR_BAD_CHAR_REF"
+;        "XML_ERROR_BINARY_ENTITY_REF"
+;        "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF"
+;        "XML_ERROR_MISPLACED_XML_PI" "XML_ERROR_UNKNOWN_ENCODING"
+;        "XML_ERROR_INCORRECT_ENCODING"
+;        "XML_ERROR_UNCLOSED_CDATA_SECTION"
+;        "XML_ERROR_EXTERNAL_ENTITY_HANDLING" "XML_OPTION_CASE_FOLDING"
+;        "XML_OPTION_TARGET_ENCODING" "XML_OPTION_SKIP_TAGSTART"
+;        "XML_OPTION_SKIP_WHITE" "YPERR_BADARGS" "YPERR_BADDB"
+;        "YPERR_BUSY" "YPERR_DOMAIN" "YPERR_KEY" "YPERR_MAP"
+;        "YPERR_NODOM" "YPERR_NOMORE" "YPERR_PMAP" "YPERR_RESRC"
+;        "YPERR_RPC" "YPERR_YPBIND" "YPERR_YPERR" "YPERR_YPSERV"
+;        "YPERR_VERS" "FORCE_GZIP" "FORCE_DEFLATE"
+
+       ;; PEAR constants
+;        "PEAR_ERROR_RETURN" "PEAR_ERROR_PRINT" "PEAR_ERROR_TRIGGER"
+;        "PEAR_ERROR_DIE" "PEAR_ERROR_CALLBACK" "OS_WINDOWS" "OS_UNIX"
+;        "PEAR_OS" "DB_OK" "DB_ERROR" "DB_ERROR_SYNTAX"
+;        "DB_ERROR_CONSTRAINT" "DB_ERROR_NOT_FOUND"
+;        "DB_ERROR_ALREADY_EXISTS" "DB_ERROR_UNSUPPORTED"
+;        "DB_ERROR_MISMATCH" "DB_ERROR_INVALID" "DB_ERROR_NOT_CAPABLE"
+;        "DB_ERROR_TRUNCATED" "DB_ERROR_INVALID_NUMBER"
+;        "DB_ERROR_INVALID_DATE" "DB_ERROR_DIVZERO"
+;        "DB_ERROR_NODBSELECTED" "DB_ERROR_CANNOT_CREATE"
+;        "DB_ERROR_CANNOT_DELETE" "DB_ERROR_CANNOT_DROP"
+;        "DB_ERROR_NOSUCHTABLE" "DB_ERROR_NOSUCHFIELD"
+;        "DB_ERROR_NEED_MORE_DATA" "DB_ERROR_NOT_LOCKED"
+;        "DB_ERROR_VALUE_COUNT_ON_ROW" "DB_ERROR_INVALID_DSN"
+;        "DB_ERROR_CONNECT_FAILED" "DB_WARNING" "DB_WARNING_READ_ONLY"
+;        "DB_PARAM_SCALAR" "DB_PARAM_OPAQUE" "DB_BINMODE_PASSTHRU"
+;        "DB_BINMODE_RETURN" "DB_BINMODE_CONVERT" "DB_FETCHMODE_DEFAULT"
+;        "DB_FETCHMODE_ORDERED" "DB_FETCHMODE_ASSOC"
+;        "DB_FETCHMODE_FLIPPED" "DB_GETMODE_ORDERED" "DB_GETMODE_ASSOC"
+;        "DB_GETMODE_FLIPPED" "DB_TABLEINFO_ORDER"
+;        "DB_TABLEINFO_ORDERTABLE" "DB_TABLEINFO_FULL"
+
+       )))
+  "PHP constants.")
+
+(defconst php-keywords
+  (eval-when-compile
+    (regexp-opt
+     ;; "class", "new" and "extends" get special treatment
+     ;; "case" and  "default" get special treatment elsewhere
+     '("and" "as" "break" "continue" "declare" "do" "echo" "else" "elseif"
+       "endfor" "endforeach" "endif" "endswitch" "endwhile" "exit"
+       "extends" "for" "foreach" "global" "if" "include" "include_once"
+       "next" "or" "require" "require_once" "return" "static" "switch"
+       "then" "var" "while" "xor" "private" "throw" "catch" "try"
+       "instanceof" "catch all" "finally")))
+  "PHP keywords.")
+
+(defconst php-identifier
+  (eval-when-compile
+    '"[a-zA-Z\_\x7f-\xff][a-zA-Z0-9\_\x7f-\xff]*")
+  "Characters in a PHP identifier.")
+
+(defconst php-types
+  (eval-when-compile
+    (regexp-opt '("array" "bool" "boolean" "char" "const" "double" "float"
+                  "int" "integer" "long" "mixed" "object" "real"
+                  "string")))
+  "PHP types.")
+
+(defconst php-superglobals
+  (eval-when-compile
+    (regexp-opt '("_GET" "_POST" "_COOKIE" "_SESSION" "_ENV" "GLOBALS"
+                  "_SERVER" "_FILES" "_REQUEST")))
+  "PHP superglobal variables.")
+
+;; Set up font locking
+(defconst php-font-lock-keywords-1
+  (list
+   ;; Fontify constants
+   (cons
+    (concat "\\<\\(" php-constants "\\)\\>")
+    'font-lock-constant-face)
+
+   ;; Fontify keywords
+   (cons
+    (concat "\\<\\(" php-keywords "\\)\\>")
+    'font-lock-keyword-face)
+
+   ;; Fontify keywords and targets, and case default tags.
+   (list "\\<\\(break\\|case\\|continue\\)\\>[ \t]*\\(-?\\(?:\\sw\\|\\s_\\)+\\)?"
+         '(1 font-lock-keyword-face) '(2 font-lock-constant-face t t))
+   ;; This must come after the one for keywords and targets.
+   '(":" ("^[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)[ \t]*:[ \t]*$"
+          (beginning-of-line) (end-of-line)
+          (1 font-lock-constant-face)))
+
+   ;; treat 'print' as keyword only when not used like a function name
+   '("\\<print\\s-*(" . php-default-face)
+   '("\\<print\\>" . font-lock-keyword-face)
+
+   ;; Fontify PHP tag
+   '("<\\?\\(php\\)?" . font-lock-constant-face)
+   '("\\?>" . font-lock-constant-face)
+
+   ;; Fontify ASP-style tag
+   '("<\\%\\(=\\)?" . font-lock-constant-face)
+   '("\\%>" . font-lock-constant-face)
+
+   )
+  "Subdued level highlighting for PHP mode.")
+
+(defconst php-font-lock-keywords-2
+  (append
+   php-font-lock-keywords-1
+   (list
+
+    ;; class declaration
+    '("[^_]*\\<\\(class\\|interface\\)[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
+      (1 font-lock-keyword-face) (2 font-lock-type-face nil t))
+    ;; handle several words specially, to include following word,
+    ;; thereby excluding it from unknown-symbol checks later
+    ;; FIX to handle implementing multiple
+    ;; currently breaks on "class Foo implements Bar, Baz"
+    '("\\<\\(new\\|extends\\|implements\\)\\s-+\\$?\\(\\(?:\\sw\\|\\s_\\)+\\)"
+      (1 font-lock-keyword-face) (2 font-lock-type-face))
+
+    ;; function declaration
+    '("\\<\\(function\\)\\s-+&?\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*("
+      (1 font-lock-keyword-face)
+      (2 font-lock-function-name-face nil t))
+
+    ;; class hierarchy
+    '("\\(self\\|parent\\)\\W" (1 font-lock-constant-face nil nil))
+
+    ;; method and variable features
+    '("\\<\\(private\\|protected\\|public\\)\\s-+\\$?\\(?:\\sw\\|\\s_\\)+"
+      (1 font-lock-keyword-face))
+
+    ;; method features
+    '("^[ \t]*\\(abstract\\|static\\|final\\)\\s-+\\$?\\(?:\\sw\\|\\s_\\)+"
+      (1 font-lock-keyword-face))
+
+    ;; variable features
+    '("^[ \t]*\\(static\\|const\\)\\s-+\\$?\\(?:\\sw\\|\\s_\\)+"
+      (1 font-lock-keyword-face))
+    ))
+  "Medium level highlighting for PHP mode.")
+
+(defconst php-font-lock-keywords-3
+  (append
+   php-font-lock-keywords-2
+   `(
+     ;; <word> or </word> for HTML
+     ;;'("</?\\sw+[^> ]*>" . font-lock-constant-face)
+     ;;'("</?\\sw+[^>]*" . font-lock-constant-face)
+     ;;'("<!DOCTYPE" . font-lock-constant-face)
+     ("</?[a-z!:]+" . font-lock-constant-face)
+
+     ;; HTML >
+     ("<[^>]*\\(>\\)" (1 font-lock-constant-face))
+
+     ;; HTML tags
+     ("\\(<[a-z]+\\)[[:space:]]+\\([a-z:]+=\\)[^>]*?" (1 font-lock-constant-face) (2 font-lock-constant-face) )
+     ("\"[[:space:]]+\\([a-z:]+=\\)" (1 font-lock-constant-face))
+
+     ;; HTML entities
+     ;;'("&\\w+;" . font-lock-variable-name-face)
+
+     ;; warn about '$' immediately after ->
+     ,@(if php-mode-dollar-property-warning
+           '("\\$\\(?:\\sw\\|\\s_\\)+->\\s-*\\(\\$\\)\\(\\(?:\\sw\\|\\s_\\)+\\)"
+             (1 font-lock-warning-face) (2 php-default-face)))
+
+     ;; warn about $word.word -- it could be a valid concatenation,
+     ;; but without any spaces we'll assume $word->word was meant.
+     ,@(if php-mode-dot-property-warning
+           '("\\$\\(?:\\sw\\|\\s_\\)+\\(\\.\\)\\sw" 1 font-lock-warning-face))
+
+     ;; Warn about ==> instead of =>
+     ("==+>" . font-lock-warning-face)
+
+     ;; exclude casts from bare-word treatment (may contain spaces)
+     (,(concat "(\\s-*\\(" php-types "\\)\\s-*)") 1 font-lock-type-face)
+
+     ;; PHP5: function declarations may contain classes as parameters type
+     (,(concat
+        "[(,]\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-+&?\\$\\(?:\\sw\\|\\s_\\)+\\>")
+      1 font-lock-type-face)
+
+     ;; Fontify variables and function calls
+     ("\\$\\(this\\|that\\)\\W" (1 font-lock-constant-face nil nil))
+     (,(concat "\\$\\(" php-superglobals "\\)\\W")
+      (1 font-lock-constant-face nil nil)) ; $_GET & co
+     ("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face)) ; $variable
+     ("->\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; ->variable
+     ("->\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" . (1 php-default-face t t)) ; ->function_call
+     ("\\(\\(?:\\sw\\|\\s_\\)+\\)::\\(?:\\sw\\|\\s_\\)+\\s-*(?" . (1 font-lock-type-face)) ; class::member
+     ("::\\(\\(?:\\sw\\|\\s_\\)+\\>[^(]\\)" . (1 php-default-face)) ; class::constant
+     ("\\<\\(?:\\sw\\|\\s_\\)+\\s-*[[(]" . php-default-face) ; word( or word[
+     ("\\<[0-9]+" . php-default-face)   ; number (also matches word)
+
+     ;; Warn on any words not already fontified
+     ,@(if php-mode-warn-on-unmatched
+           '("\\<\\(?:\\sw\\|\\s_\\)+\\>" . font-lock-warning-face))
+
+     )
+   )
+  "Gauchy level highlighting for PHP mode.")
+
+;; Define the imenu-generic-expression for PHP mode.
+;; To use, execute M-x imenu, then click on Functions or Classes,
+;; then select given function/class name to go to its definition.
+;; [Contributed by Gerrit Riessen]
+(defvar php-imenu-generic-expression
+ '(
+   ("All Functions"
+    "^\\s-*function\\s-+\\([[:alnum:]_]+\\)\\s-*(" 1)
+   ("Classes"
+    "^\\s-*class\\s-+\\([[:alnum:]_]+\\)\\s-*" 1)
+   ("Public Methods"
+    "^\\s-*public function\\s-+\\([[:alnum:]_]+\\)\\s-*(" 1)
+   ("Protected Methods"
+    "^\\s-*protected function\\s-+\\([[:alnum:]_]+\\)\\s-*(" 1)
+   ("Private Methods"
+    "^\\s-*private function\\s-+\\([[:alnum:]_]+\\)\\s-*(" 1)
+   )
+ "Imenu generic expression for PHP Mode. See `imenu-generic-expression'."
+ )
+
+(defconst php-block-stmt-1-kwds '("do" "else" "finally" "try"))
+(defconst php-block-stmt-2-kwds
+  '("for" "if" "while" "switch" "foreach" "elseif"  "catch all"))
+
+(defconst php-block-stmt-1-key
+  (regexp-opt php-block-stmt-1-kwds))
+(defconst php-block-stmt-2-key
+  (regexp-opt php-block-stmt-2-kwds))
+
+(defconst php-class-decl-kwds '("class" "interface"))
+
+(defconst php-class-key
+  (concat
+   "\\(" (regexp-opt php-class-decl-kwds) "\\)\\s +"
+   c-symbol-key                                 ;; Class name.
+   "\\(\\s *extends\\s *" c-symbol-key "\\)?"   ;; Name of superclass.
+   "\\(\\s *implements *[^{]+{\\)?")) ;; List of any adopted protocols.
+
+;; Create "php-default-face" symbol for GNU Emacs so that both XEmacs
+;; and GNU emacs can refer to the default face.
+(unless (boundp 'php-default-face)
+   (defvar php-default-face 'php-default-face))
+
+;; Create faces for XEmacs
+(when (featurep 'xemacs)
+  (unless (boundp 'font-lock-keyword-face)
+    (copy-face 'bold 'font-lock-keyword-face))
+  (unless (boundp 'font-lock-constant-face)
+    (copy-face 'font-lock-keyword-face 'font-lock-constant-face)))
+
+(provide 'php-mode)
+
+;;; php-mode.el ends here