Those who work with several repos at the same time may appreciate this:

(defvar magit-repos-alias-alist '()
  "Each element is (ALIAS . DIRECTORY). Used in
`magit-switch-to-status-buffer' for quickly creating status
buffers on the listed directories. Example:

\(add-to-list 'magit-repos-alias-alist '(\"home\" . \"~\"))")


(defun magit-switch-to-status-buffer ()
  "Asks for a magit status buffer to switch to, with
completion. The possible completions include the ALIAS contained
in `magit-repos-alias-alist' (if there are no status buffers for
them yet), `.ask' for asking for a directory and `.here' if the
current buffer is under a git repository without associated
status buffer and not listed in `magit-repos-alias-alist'.

A sensible default is provided, so while working with versioned
files invoking this function and pressing ENTER at the prompt
does the Right Thing, unless you want to switch to another repo."
  (interactive)
  (let ((name-list) (buffer) (b "")
        (current-status-buffer (magit-find-status-buffer))
        (current-top-dir (magit-get-top-dir default-directory))
        (repo-name-fn
         (lambda (buf)
           (and (string-match "\\*magit: \\(.+\\)\\*" (buffer-name buf))
                (list (match-string 1 (buffer-name buf)))))))
    ;; Add the existing status buffers, but not the current one:
    (dolist (buffer (buffer-list))
      (when (and (not (eq current-status-buffer buffer))
                 (funcall repo-name-fn buffer))
        (setq name-list (append name-list (funcall repo-name-fn buffer)))))
    ;; Add the status buffer that dominates the current directory:
    (when current-status-buffer
      (if (eq current-status-buffer (current-buffer))
          (setq name-list
                (append name-list (funcall repo-name-fn current-status-buffer)))
        (setq name-list
              (append (funcall repo-name-fn current-status-buffer) name-list))))
    ;; Add the repos listed in magit-repos-alias-alist unless they
    ;; already are on the name-list:
    (dolist (repo magit-repos-alias-alist)
      (let ((dir (file-name-as-directory (expand-file-name (cdr repo)))))
        (unless (magit-find-buffer 'status dir)
          (if (or current-status-buffer
                  (not (string= current-top-dir dir)))
              (setq name-list
                    (append name-list (list (concat (car repo) ".create"))))
            (setq name-list
                  (append (list (concat (car repo) ".create")) name-list))
            (setq current-status-buffer t)))))
    ;; Add an item for creating an new status buffer:
    (if current-status-buffer
        (setq name-list (append name-list '(".ask")))
      (setq name-list (append '(".ask") name-list)))
    ;; If we are within an unknown git repo, offer it as the default:
    (when (and (not current-status-buffer) current-top-dir)
      (setq name-list (append '(".here") name-list)))
    ;; Ask:
    (setq b (funcall magit-completing-read
                     "Magit status buffer: " name-list
                     nil t nil nil (car name-list)))
    ;; Switch to the status buffer (creating it first if necessary):
    (cond
     ((string= b "") t)
     ((string-match "\\(.+\\)\\.create" b)
      (let ((dir (cdr (assoc (match-string 1 b) magit-repos-alias-alist))))
      (magit-status (file-name-as-directory dir))))
     ((string= b ".here")
      (magit-status current-top-dir))
     ((string= b ".ask")
      (magit-status (magit-read-top-dir nil)))
     (t
      (switch-to-buffer (concat "*magit: " b "*"))
      (magit-refresh)))))

Reply via email to