about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el
diff options
context:
space:
mode:
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el')
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el498
1 files changed, 498 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el
new file mode 100644
index 000000000000..875b6294c26b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el
@@ -0,0 +1,498 @@
+;;; magit-submodule.el --- submodule support for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2011-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; 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.
+
+;;; Code:
+
+(require 'magit)
+
+(defvar x-stretch-cursor)
+(defvar bookmark-make-record-function)
+
+;;; Options
+
+(defcustom magit-module-sections-hook
+  '(magit-insert-modules-overview
+    magit-insert-modules-unpulled-from-upstream
+    magit-insert-modules-unpulled-from-pushremote
+    magit-insert-modules-unpushed-to-upstream
+    magit-insert-modules-unpushed-to-pushremote)
+  "Hook run by `magit-insert-modules'.
+
+That function isn't part of `magit-status-sections-hook's default
+value, so you have to add it yourself for this hook to have any
+effect."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-status
+  :type 'hook)
+
+(defcustom magit-module-sections-nested t
+  "Whether `magit-insert-modules' wraps inserted sections.
+
+If this is non-nil, then only a single top-level section
+is inserted.  If it is nil, then all sections listed in
+`magit-module-sections-hook' become top-level sections."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-status
+  :type 'boolean)
+
+(defcustom magit-submodule-list-mode-hook '(hl-line-mode)
+  "Hook run after entering Magit-Submodule-List mode."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-repolist
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(hl-line-mode))
+
+(defcustom magit-submodule-list-columns
+  '(("Path"     25 magit-modulelist-column-path   nil)
+    ("Version"  25 magit-repolist-column-version  nil)
+    ("Branch"   20 magit-repolist-column-branch   nil)
+    ("B<U" 3 magit-repolist-column-unpulled-from-upstream   ((:right-align t)))
+    ("B>U" 3 magit-repolist-column-unpushed-to-upstream     ((:right-align t)))
+    ("B<P" 3 magit-repolist-column-unpulled-from-pushremote ((:right-align t)))
+    ("B>P" 3 magit-repolist-column-unpushed-to-pushremote   ((:right-align t)))
+    ("B"   3 magit-repolist-column-branches                 ((:right-align t)))
+    ("S"   3 magit-repolist-column-stashes                  ((:right-align t))))
+  "List of columns displayed by `magit-list-submodules'.
+
+Each element has the form (HEADER WIDTH FORMAT PROPS).
+
+HEADER is the string displayed in the header.  WIDTH is the width
+of the column.  FORMAT is a function that is called with one
+argument, the repository identification (usually its basename),
+and with `default-directory' bound to the toplevel of its working
+tree.  It has to return a string to be inserted or nil.  PROPS is
+an alist that supports the keys `:right-align' and `:pad-right'."
+  :package-version '(magit . "2.8.0")
+  :group 'magit-repolist-mode
+  :type `(repeat (list :tag "Column"
+                       (string   :tag "Header Label")
+                       (integer  :tag "Column Width")
+                       (function :tag "Inserter Function")
+                       (repeat   :tag "Properties"
+                                 (list (choice :tag "Property"
+                                               (const :right-align)
+                                               (const :pad-right)
+                                               (symbol))
+                                       (sexp   :tag "Value"))))))
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-submodule-popup "magit-submodule" nil t)
+(magit-define-popup magit-submodule-popup
+  "Popup console for submodule commands."
+  :man-page "git-submodule"
+  :switches '((?f "Force"            "--force")
+              (?r "Recursive"        "--recursive")
+              (?N "Do not fetch"     "--no-fetch")
+              (?C "Checkout tip"     "--checkout")
+              (?R "Rebase onto tip"  "--rebase")
+              (?M "Merge tip"        "--merge")
+              (?U "Use upstream tip" "--remote"))
+  :actions
+  '((?a "Add            git submodule add [--force]"
+        magit-submodule-add)
+    (?r "Register       git submodule init"
+        magit-submodule-register)
+    (?p "Populate       git submodule update --init"
+        magit-submodule-populate)
+    (?u "Update         git submodule update [--force] [--no-fetch]
+                     [--remote] [--recursive] [--checkout|--rebase|--merge]"
+        magit-submodule-update)
+    (?s "Synchronize    git submodule sync [--recursive]"
+        magit-submodule-synchronize)
+    (?d "Unpopulate     git submodule deinit [--force]"
+        magit-submodule-unpopulate)
+    nil
+    (?l "List all modules"  magit-list-submodules)
+    (?f "Fetch all modules" magit-fetch-modules))
+  :max-action-columns 1)
+
+(defun magit-submodule-filtered-arguments (&rest filters)
+  (--filter (and (member it filters) it)
+            (magit-submodule-arguments)))
+
+;;;###autoload
+(defun magit-submodule-add (url &optional path name args)
+  "Add the repository at URL as a module.
+
+Optional PATH is the path to the module relative to the root of
+the superproject.  If it is nil, then the path is determined
+based on the URL.  Optional NAME is the name of the module.  If
+it is nil, then PATH also becomes the name."
+  (interactive
+   (magit-with-toplevel
+     (let* ((url (magit-read-string-ns "Add submodule (remote url)"))
+            (path (let ((read-file-name-function
+                         (if (or (eq read-file-name-function 'ido-read-file-name)
+                                 (advice-function-member-p
+                                  'ido-read-file-name
+                                  read-file-name-function))
+                             ;; The Ido variant doesn't work properly here.
+                             #'read-file-name-default
+                           read-file-name-function)))
+                    (directory-file-name
+                     (file-relative-name
+                      (read-directory-name
+                       "Add submodules at path: " nil nil nil
+                       (and (string-match "\\([^./]+\\)\\(\\.git\\)?$" url)
+                            (match-string 1 url))))))))
+       (list url
+             (directory-file-name path)
+             (magit-submodule-read-name-for-path path)
+             (magit-submodule-filtered-arguments "--force")))))
+  (magit-with-toplevel
+    (magit-call-git "submodule" "add" (and name (list "--name" name))
+                    args "--" url path)
+    (unless (version< (magit-git-version) "2.11.0")
+      (magit-call-git "submodule" "absorbgitdirs" path))
+    (magit-refresh)))
+
+;;;###autoload
+(defun magit-submodule-read-name-for-path (path &optional prefer-short)
+  (let* ((path (directory-file-name (file-relative-name path)))
+         (name (file-name-nondirectory path)))
+    (push (if prefer-short path name) minibuffer-history)
+    (magit-read-string-ns
+     "Submodule name" nil (cons 'minibuffer-history 2)
+     (or (--keep (pcase-let ((`(,var ,val) (split-string it "=")))
+                   (and (equal val path)
+                        (cadr (split-string var "\\."))))
+                 (magit-git-lines "config" "--list" "-f" ".gitmodules"))
+         (if prefer-short name path)))))
+
+;;;###autoload
+(defun magit-submodule-register (modules)
+  "Register MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; This command and the underlying "git submodule init" do NOT
+  ;; "initialize" modules.  They merely "register" modules in the
+  ;; super-projects $GIT_DIR/config file, the purpose of which is to
+  ;; allow users to change such values before actually initializing
+  ;; the modules.
+  (interactive
+   (list (magit-module-confirm "Register" 'magit-module-no-worktree-p)))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "init" "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-populate (modules)
+  "Create MODULES working directories, checking out the recorded commits.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; This is the command that actually "initializes" modules.
+  ;; A module is initialized when it has a working directory,
+  ;; a gitlink, and a .gitmodules entry.
+  (interactive
+   (list (magit-module-confirm "Populate" 'magit-module-no-worktree-p)))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "update" "--init" "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-update (modules args)
+  "Update MODULES by checking out the recorded commits.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; Unlike `git-submodule's `update' command ours can only update
+  ;; "initialized" modules by checking out other commits but not
+  ;; "initialize" modules by creating the working directories.
+  ;; To do the latter we provide the "setup" command.
+  (interactive
+   (list (magit-module-confirm "Update" 'magit-module-worktree-p)
+         (magit-submodule-filtered-arguments
+          "--force" "--remote" "--recursive" "--checkout" "--rebase" "--merge"
+          "--no-fetch")))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "update" args "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-synchronize (modules args)
+  "Synchronize url configuration of MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  (interactive
+   (list (magit-module-confirm "Synchronize" 'magit-module-worktree-p)
+         (magit-submodule-filtered-arguments "--recursive")))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "sync" args "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-unpopulate (modules args)
+  "Remove working directories of MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; Even though a package is "uninitialized" (it has no worktree)
+  ;; the super-projects $GIT_DIR/config may never-the-less set the
+  ;; module's url.  This may happen if you `deinit' and then `init'
+  ;; to register (NOT initialize).  Because the purpose of `deinit'
+  ;; is to remove the working directory AND to remove the url, this
+  ;; command does not limit itself to modules that have no working
+  ;; directory.
+  (interactive
+   (list (magit-module-confirm "Unpopulate")
+         (magit-submodule-filtered-arguments "--force")))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "deinit" args "--" modules)))
+
+;;; Sections
+
+;;;###autoload
+(defun magit-insert-modules ()
+  "Insert submodule sections.
+Hook `magit-module-sections-hook' controls which module sections
+are inserted, and option `magit-module-sections-nested' controls
+whether they are wrapped in an additional section."
+  (when-let ((modules (magit-list-module-paths)))
+    (if magit-module-sections-nested
+        (magit-insert-section section (submodules nil t)
+          (magit-insert-heading
+            (format "%s (%s)"
+                    (propertize "Modules" 'face 'magit-section-heading)
+                    (length modules)))
+          (if (oref section hidden)
+              (oset section washer 'magit--insert-modules)
+            (magit--insert-modules)))
+      (magit--insert-modules))))
+
+(defun magit--insert-modules (&optional _section)
+  (magit-run-section-hook 'magit-module-sections-hook))
+
+;;;###autoload
+(defun magit-insert-modules-overview ()
+  "Insert sections for all modules.
+For each section insert the path and the output of `git describe --tags',
+or, failing that, the abbreviated HEAD commit hash."
+  (when-let ((modules (magit-list-module-paths)))
+    (magit-insert-section section (submodules nil t)
+      (magit-insert-heading
+        (format "%s (%s)"
+                (propertize "Modules overview" 'face 'magit-section-heading)
+                (length modules)))
+      (if (oref section hidden)
+          (oset section washer 'magit--insert-modules-overview)
+        (magit--insert-modules-overview)))))
+
+(defvar magit-modules-overview-align-numbers t)
+
+(defun magit--insert-modules-overview (&optional _section)
+  (magit-with-toplevel
+    (let* ((modules (magit-list-module-paths))
+           (path-format (format "%%-%is "
+                                (min (apply 'max (mapcar 'length modules))
+                                     (/ (window-width) 2))))
+           (branch-format (format "%%-%is " (min 25 (/ (window-width) 3)))))
+      (dolist (module modules)
+        (let ((default-directory
+                (expand-file-name (file-name-as-directory module))))
+          (magit-insert-section (submodule module t)
+            (insert (propertize (format path-format module)
+                                'face 'magit-diff-file-heading))
+            (if (not (file-exists-p ".git"))
+                (insert "(unpopulated)")
+              (insert (format branch-format
+                              (--if-let (magit-get-current-branch)
+                                  (propertize it 'face 'magit-branch-local)
+                                (propertize "(detached)" 'face 'warning))))
+              (--if-let (magit-git-string "describe" "--tags")
+                  (progn (when (and magit-modules-overview-align-numbers
+                                    (string-match-p "\\`[0-9]" it))
+                           (insert ?\s))
+                         (insert (propertize it 'face 'magit-tag)))
+                (--when-let (magit-rev-format "%h")
+                  (insert (propertize it 'face 'magit-hash)))))
+            (insert ?\n))))))
+  (insert ?\n))
+
+(defvar magit-submodules-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-list-submodules)
+    map)
+  "Keymap for `submodules' sections.")
+
+(defvar magit-submodule-section-map
+  (let ((map (make-sparse-keymap)))
+    (unless (featurep 'jkl)
+      (define-key map "\C-j"   'magit-submodule-visit))
+    (define-key map [C-return] 'magit-submodule-visit)
+    (define-key map [remap magit-visit-thing]  'magit-submodule-visit)
+    (define-key map [remap magit-delete-thing] 'magit-submodule-deinit)
+    (define-key map "K" 'magit-file-untrack)
+    (define-key map "R" 'magit-file-rename)
+    map)
+  "Keymap for `submodule' sections.")
+
+(defun magit-submodule-visit (module &optional other-window)
+  "Visit MODULE by calling `magit-status' on it.
+Offer to initialize MODULE if it's not checked out yet.
+With a prefix argument, visit in another window."
+  (interactive (list (or (magit-section-when submodule)
+                         (magit-read-module-path "Visit module"))
+                     current-prefix-arg))
+  (magit-with-toplevel
+    (let ((path (expand-file-name module)))
+      (if (and (not (file-exists-p (expand-file-name ".git" module)))
+               (not (y-or-n-p (format "Initialize submodule '%s' first?"
+                                      module))))
+          (when (file-exists-p path)
+            (dired-jump other-window (concat path "/.")))
+        (magit-run-git-async "submodule" "update" "--init" "--" module)
+        (set-process-sentinel
+         magit-this-process
+         (lambda (process event)
+           (let ((magit-process-raise-error t))
+             (magit-process-sentinel process event))
+           (when (and (eq (process-status      process) 'exit)
+                      (=  (process-exit-status process) 0))
+             (magit-diff-visit-directory path other-window))))))))
+
+;;;###autoload
+(defun magit-insert-modules-unpulled-from-upstream ()
+  "Insert sections for modules that haven't been pulled from the upstream.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unpulled from @{upstream}"
+                              'modules-unpulled-from-upstream
+                              "HEAD..@{upstream}"))
+
+;;;###autoload
+(defun magit-insert-modules-unpulled-from-pushremote ()
+  "Insert sections for modules that haven't been pulled from the push-remote.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unpulled from ${push}"
+                              'modules-unpulled-from-pushremote
+                              "HEAD..@{push}"))
+
+;;;###autoload
+(defun magit-insert-modules-unpushed-to-upstream ()
+  "Insert sections for modules that haven't been pushed to the upstream.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unmerged into @{upstream}"
+                              'modules-unpushed-to-upstream
+                              "@{upstream}..HEAD"))
+
+;;;###autoload
+(defun magit-insert-modules-unpushed-to-pushremote ()
+  "Insert sections for modules that haven't been pushed to the push-remote.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unpushed to @{push}"
+                              'modules-unpushed-to-pushremote
+                              "${push}..HEAD"))
+
+(defun magit--insert-modules-logs (heading type range)
+  "For internal use, don't add to a hook."
+  (when-let ((modules (magit-list-module-paths)))
+    (magit-insert-section section ((eval type) nil t)
+      (string-match "\\`\\(.+\\) \\([^ ]+\\)\\'" heading)
+      (magit-insert-heading
+        (concat
+         (propertize (match-string 1 heading) 'face 'magit-section-heading) " "
+         (propertize (match-string 2 heading) 'face 'magit-branch-remote) ":"))
+      (magit-with-toplevel
+        (dolist (module modules)
+          (when (magit-module-worktree-p module)
+            (let ((default-directory
+                    (expand-file-name (file-name-as-directory module))))
+              (when (magit-file-accessible-directory-p default-directory)
+                (magit-insert-section sec (file module t)
+                  (magit-insert-heading
+                    (concat (propertize module 'face 'magit-diff-file-heading) ":"))
+                  (magit-git-wash (apply-partially 'magit-log-wash-log 'module)
+                    "-c" "push.default=current" "log" "--oneline" range)
+                  (when (> (point)
+                           (oref sec content))
+                    (delete-char -1))))))))
+      (if (> (point)
+             (oref section content))
+          (insert ?\n)
+        (magit-cancel-section)))))
+
+;;; List
+
+;;;###autoload
+(defun magit-list-submodules ()
+  "Display a list of the current repository's submodules."
+  (interactive)
+  (magit-display-buffer (magit-mode-get-buffer 'magit-submodule-list-mode t))
+  (magit-submodule-list-mode)
+  (magit-submodule-list-refresh)
+  (tabulated-list-print))
+
+(defvar magit-submodule-list-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-repolist-mode-map)
+    map)
+  "Local keymap for Magit-Submodule-List mode buffers.")
+
+(define-derived-mode magit-submodule-list-mode tabulated-list-mode "Modules"
+  "Major mode for browsing a list of Git submodules."
+  :group 'magit-repolist-mode
+  (setq x-stretch-cursor        nil)
+  (setq tabulated-list-padding  0)
+  (setq tabulated-list-sort-key (cons "Path" nil))
+  (setq tabulated-list-format
+        (vconcat (mapcar (pcase-lambda (`(,title ,width ,_fn ,props))
+                           (nconc (list title width t)
+                                  (-flatten props)))
+                         magit-submodule-list-columns)))
+  (tabulated-list-init-header)
+  (add-hook 'tabulated-list-revert-hook 'magit-submodule-list-refresh nil t)
+  (setq imenu-prev-index-position-function
+        #'magit-imenu--submodule-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        #'magit-imenu--submodule-extract-index-name-function)
+  (setq-local bookmark-make-record-function
+              #'magit-bookmark--submodules-make-record))
+
+(defun magit-submodule-list-refresh ()
+  (setq tabulated-list-entries
+        (-keep (lambda (module)
+                 (let ((default-directory
+                         (expand-file-name (file-name-as-directory module))))
+                   (and (file-exists-p ".git")
+                        (list module
+                              (vconcat
+                               (--map (or (funcall (nth 2 it) module) "")
+                                      magit-submodule-list-columns))))))
+               (magit-list-module-paths))))
+
+(defun magit-modulelist-column-path (path)
+  "Insert the relative path of the submodule."
+  path)
+
+(provide 'magit-submodule)
+;;; magit-submodule.el ends here