[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/git-commit f0296148a6 2/2: Support acting on entries in re
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/git-commit f0296148a6 2/2: Support acting on entries in repolist buffers |
Date: |
Sun, 20 Feb 2022 12:58:01 -0500 (EST) |
branch: elpa/git-commit
commit f0296148a64f8058f920e3ae90c418087c966344
Author: Jonas Bernoulli <jonas@bernoul.li>
Commit: Jonas Bernoulli <jonas@bernoul.li>
Support acting on entries in repolist buffers
Closes #4453.
---
docs/magit.org | 28 ++++++++++++++++
docs/magit.texi | 35 ++++++++++++++++++++
lisp/magit-repos.el | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 156 insertions(+)
diff --git a/docs/magit.org b/docs/magit.org
index c671c67590..bd0d5ccd18 100644
--- a/docs/magit.org
+++ b/docs/magit.org
@@ -2494,6 +2494,7 @@ buffers.
and set ~:pad-right~ to 0. ~+~ is substituted for numbers higher
than 9.
+#+texinfo: @noindent
The following functions can be added to the above option:
- Function: magit-repolist-column-ident ::
@@ -2559,6 +2560,33 @@ The following functions can be added to the above option:
This function inserts the number of commits in the current branch
but not its push branch.
+#+texinfo: @noindent
+The following commands are available in repolist buffers:
+
+- Key: RET (magit-repolist-status) ::
+
+ This command shows the status for the repository at point.
+
+- Key: m (magit-repolist-mark) ::
+
+ This command marks the repository at point.
+
+- Key: u (magit-repolist-unmark) ::
+
+ This command unmarks the repository at point.
+
+- Key: f (magit-repolist-fetch) ::
+
+ This command fetches all marked repositories. If no repositories
+ are marked, then it offers to fetch all displayed repositories.
+
+- Key: 5 (magit-repolist-find-file-other-frame) ::
+
+ This command reads a relative file-name (without completion) and
+ opens the respective file in each marked repository in a new frame.
+ If no repositories are marked, then it offers to do this for all
+ displayed repositories.
+
** Logging
The status buffer contains logs for the unpushed and unpulled commits,
diff --git a/docs/magit.texi b/docs/magit.texi
index 6e3d787dd4..0a8028fbb5 100644
--- a/docs/magit.texi
+++ b/docs/magit.texi
@@ -3108,6 +3108,7 @@ and set @code{:pad-right} to 0. @code{+} is substituted
for numbers higher
than 9.
@end defopt
+@noindent
The following functions can be added to the above option:
@defun magit-repolist-column-ident
@@ -3178,6 +3179,40 @@ This function inserts the number of commits in the
current branch
but not its push branch.
@end defun
+@noindent
+The following commands are available in repolist buffers:
+
+@table @asis
+@item @kbd{@key{RET}} (@code{magit-repolist-status})
+@kindex RET
+@findex magit-repolist-status
+This command shows the status for the repository at point.
+
+@item @kbd{m} (@code{magit-repolist-mark})
+@kindex m
+@findex magit-repolist-mark
+This command marks the repository at point.
+
+@item @kbd{u} (@code{magit-repolist-unmark})
+@kindex u
+@findex magit-repolist-unmark
+This command unmarks the repository at point.
+
+@item @kbd{f} (@code{magit-repolist-fetch})
+@kindex f
+@findex magit-repolist-fetch
+This command fetches all marked repositories. If no repositories
+are marked, then it offers to fetch all displayed repositories.
+
+@item @kbd{5} (@code{magit-repolist-find-file-other-frame})
+@kindex 5
+@findex magit-repolist-find-file-other-frame
+This command reads a relative file-name (without completion) and
+opens the respective file in each marked repository in a new frame.
+If no repositories are marked, then it offers to do this for all
+displayed repositories.
+@end table
+
@node Logging
@section Logging
diff --git a/lisp/magit-repos.el b/lisp/magit-repos.el
index 8997a1a9ff..684c838d73 100644
--- a/lisp/magit-repos.el
+++ b/lisp/magit-repos.el
@@ -156,12 +156,105 @@ repositories are displayed."
(magit-status-setup-buffer (expand-file-name it))
(user-error "There is no repository at point")))
+(defun magit-repolist-mark ()
+ "Mark a repository and move to the next line."
+ (interactive)
+ (magit-repolist--ensure-padding)
+ (tabulated-list-put-tag "*" t))
+
+(defun magit-repolist-unmark ()
+ "Unmark a repository and move to the next line."
+ (interactive)
+ (tabulated-list-put-tag " " t))
+
+(defun magit-repolist-fetch (repos)
+ "Fetch all marked or listed repositories."
+ (interactive (list (magit-repolist--get-repos ?*)))
+ (run-hooks 'magit-credential-hook)
+ (magit-repolist--mapc (apply-partially #'magit-run-git "remote" "update")
+ repos "Fetching in %s..."))
+
+(defun magit-repolist-find-file-other-frame (repos file)
+ "Find a file in all marked or listed repositories."
+ (interactive (list (magit-repolist--get-repos ?*)
+ (read-string "Find file in repositories: ")))
+ (magit-repolist--mapc (apply-partially #'find-file-other-frame file) repos))
+
+(defun magit-repolist--ensure-padding ()
+ "Set `tabulated-list-padding' to 2, unless that is already non-zero."
+ (when (zerop tabulated-list-padding)
+ (setq tabulated-list-padding 2)
+ (tabulated-list-init-header)
+ (tabulated-list-print t)))
+
+(defun magit-repolist--get-repos (&optional char)
+ "Return marked repositories or `all' if none are marked.
+If optional CHAR is non-nil, then only return repositories
+marked with that character. If no repositories are marked
+then ask whether to act on all repositories instead."
+ (or (magit-repolist--marked-repos char)
+ (if (magit-confirm 'repolist-all
+ "Nothing selected. Act on ALL displayed repositories")
+ 'all
+ (user-error "Abort"))))
+
+(defun magit-repolist--marked-repos (&optional char)
+ "Return marked repositories.
+If optional CHAR is non-nil, then only return repositories
+marked with that character."
+ (let (c list)
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (setq c (char-after))
+ (unless (eq c ?\s)
+ (if char
+ (when (eq c char)
+ (push (tabulated-list-get-id) list))
+ (push (cons c (tabulated-list-get-id)) list)))
+ (forward-line)))
+ list))
+
+(defun magit-repolist--mapc (fn repos &optional msg)
+ "Apply FN to each directory in REPOS for side effects only.
+If REPOS is the symbol `all', then call FN for all displayed
+repositories. When FN is called, `default-directory' is bound to
+the top-level directory of the current repository. If optional
+MSG is non-nil then that is displayed around each call to FN.
+If it contains \"%s\" then the directory is substituted for that."
+ (when (eq repos 'all)
+ (setq repos nil)
+ (save-excursion
+ (goto-char (point-min))
+ (while (not (eobp))
+ (push (tabulated-list-get-id) repos)
+ (forward-line)))
+ (setq repos (nreverse repos)))
+ (let ((base default-directory)
+ (len (length repos))
+ (i 0))
+ (mapc (lambda (repo)
+ (let ((default-directory
+ (file-name-as-directory (expand-file-name repo base))))
+ (if msg
+ (let ((msg (concat (format "(%s/%s) " (cl-incf i) len)
+ (format msg default-directory))))
+ (message msg)
+ (funcall fn)
+ (message (concat msg "done")))
+ (funcall fn))))
+ repos)))
+
;;;; Mode
(defvar magit-repolist-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map tabulated-list-mode-map)
(define-key map (kbd "C-m") 'magit-repolist-status)
+ (define-key map (kbd "m") 'magit-repolist-mark)
+ (define-key map (kbd "u") 'magit-repolist-unmark)
+ (define-key map (kbd "f") 'magit-repolist-fetch)
+ (define-key map (kbd "5") 'magit-repolist-find-file-other-frame)
map)
"Local keymap for Magit-Repolist mode buffers.")