diff --git a/magit.el b/magit.el index 59430cd1..98c1a466 100644 --- a/magit.el +++ b/magit.el @@ -3553,10 +3553,14 @@ Prefix arg means justify as well." (define-key map (kbd "M") 'magit-branches-window-automatic-merge) (define-key map (kbd "$") 'magit-display-process) (define-key map (kbd "q") 'magit-quit-branches-window) + (define-key map (kbd "g") 'magit-show-branches) (define-key map (kbd "V") 'magit-show-branches) + (define-key map (kbd "n") 'next-line) + (define-key map (kbd "p") 'previous-line) map)) -(define-derived-mode magit-show-branches-mode text-mode "Magit Branches") +(define-derived-mode magit-show-branches-mode fundamental-mode + "Magit Branches") (defun magit-quit-branches-window () "Bury the branches buffer and delete its window." @@ -3565,19 +3569,13 @@ Prefix arg means justify as well." (delete-window)) (defun magit--branch-name-from-line (line) - "Extract the branch name from one line of 'git branch' output. -Will remove the 'remotes/' prefix if it exists." - (save-match-data - (if (string-match "^[[:blank:]]*\\*?[[:blank:]]+\\(remotes/\\)?\\([^[:blank:]]+\\)[[:blank:]]" line) - (match-string 2 line)))) + "Extract the branch name from one line of 'git branch' output." + (get-text-property 0 'branch-name line)) (defun magit--branch-name-at-point () "Get the branch name in the line at point." (let ((branch (magit--branch-name-from-line (thing-at-point 'line)))) - (if (or (= (point) (point-max)) - (not branch)) - (error "No branch found in current line")) - branch)) + (or branch (error "No branch at point")))) (defun magit-branches-window-checkout () "Check out the branch in the line at point." @@ -3592,7 +3590,7 @@ With prefix force the removal even it it hasn't been merged." (interactive "P") (let ((args (list "branch" (if force "-D" "-d") - (if (magit--is-branch-at-point-remote) "-r") + (when (magit--is-branch-at-point-remote) "-r") (magit--branch-name-at-point)))) (save-excursion (apply 'magit-run-git (remq nil args)) @@ -3611,29 +3609,64 @@ With prefix force the removal even it it hasn't been merged." (magit-show-branches)) (defvar magit-branches-buffer-name "*magit-branches*") -(defvar magit-number-local-branches nil - "Number of local branches for the branches window") (defun magit--is-branch-at-point-remote() "Return t if the branch at point is a remote tracking branch" - (> (line-number-at-pos) (or magit-number-local-branches 0))) + (get-text-property (point) 'remote)) + +(defun magit--branch-view-details (branch-line) + "Extract details from branch -va output." + (string-match (concat + "^\\(\\*? \\{1,2\\}\\)" ; current branch marker (maybe) + "\\(remotes/\\)?\\(.+?\\) +" ; is it remote, branch name + + "\\(?:" + "\\([0-9a-fA-F]\\{7\\}\\) " ; sha1 + "\\|\\(-> \\)" ; or the pointer to a ref + "\\)" + + "\\(.+\\)" ; message or ref + ) + branch-line) + (let ((res (list (cons 'current (match-string 1 branch-line)) + (cons 'remote (not (not (match-string 2 branch-line)))) + (cons 'branch (match-string 3 branch-line))))) + (if (match-string 5 branch-line) + (cons (cons 'other-ref (match-string 6 branch-line)) res) + (append + (list + (cons 'sha1 (match-string 4 branch-line)) + (cons 'msg (match-string 6 branch-line))) + res)))) (defun magit-show-branches () "Show all of the current branches in other-window." (interactive) - (save-selected-window - (unless (string= (buffer-name) magit-branches-buffer-name) - (switch-to-buffer-other-window magit-branches-buffer-name)) - (let ((inhibit-read-only t)) - (erase-buffer) - (insert (magit-git-string "branch" "-va")) - (insert "\n")) - (magit-show-branches-mode) - (set (make-local-variable 'magit-number-local-branches) - (with-temp-buffer - (insert (magit-git-string "branch")) - (line-number-at-pos))) - (setq buffer-read-only t))) + (unless (string= (buffer-name) magit-branches-buffer-name) + (switch-to-buffer-other-window magit-branches-buffer-name)) + (let ((inhibit-read-only t) + (branches (mapcar 'magit--branch-view-details + (magit-git-lines "branch" "-va")))) + (erase-buffer) + (insert + (mapconcat + (lambda (b) + (propertize + (concat + (cdr (assoc 'current b)) + (propertize (or (cdr (assoc 'sha1 b)) + " ") + 'face 'magit-log-sha1) + " " + (cdr (assoc 'branch b)) + (when (assoc 'other-ref b) + (concat " (" (cdr (assoc 'other-ref b)) ")"))) + 'remote (cdr (assoc 'remote b)) + 'branch-name (cdr (assoc 'branch b)))) + branches + "\n")) + (magit-show-branches-mode)) + (setq buffer-read-only t)) (defvar magit-ediff-file) (defvar magit-ediff-windows)