0

I'm a new user of magit and I'm currently using it in a separate frame with a single window (magit-status). I'd like that to show the git status of the project of the latest visited buffer. Imagine that in another frame I have two windows with two buffers of files of two different projects. I'd like the magit window to show me the git status of the project depending on the current selected buffer.

2 Answers 2

2

As @tarsius says, I think you'll probably have to put something together yourself to get what you want. To hopefully get you closer to doing that, I'll try to solve a part of the problem.

Here's the helpful diagram you gave in your duplicate stackoverflow question:

        frame 1                  frame 2
***********************     ****************
* window 1 * window 2 *     *    window3   *
*          *          *     *              *
*   file   *   file   *     * magit-status *
* of proj1 * of proj2 *     *              *
*          *          *     *              *
***********************     ****************

So if you switch from the buffer in window 1 to the buffer in window 2, you want window 3 to show the status for the repository that buffer 2's file belongs to.

The part of the problem that I'm going to ignore is how to detect the buffer switch (or whatever specific events you're interested in catching). In addition to the library that @tarsius points to (which I'm unfamiliar with), you could also try using buffer-list-update-hook.

For now, let's just say that you only want window 3 to be updated when you interactively call other-window. In that case, one option would be to write a wrapper around it, like the function below. This wrapper compares the repository before the call to the repository after, and, if they are different, it searches for a visible Magit status buffer to update.

(defun my/other-window ()
  (interactive)
  (let ((project-previous (magit-toplevel)))
    (call-interactively #'other-window)
    (let ((project (magit-toplevel)))
      (when (and project
                 (not (equal project-previous project)))
        (let ((status-win
               (cl-some (lambda (b)
                          (and (with-current-buffer b
                                 (derived-mode-p 'magit-status-mode))
                               (get-buffer-window b 'visible)))
                        (buffer-list)))
              (magit-display-buffer-noselect t)
              (magit-display-buffer-function
               (lambda (buffer)
                 (display-buffer buffer '(display-buffer-same-window)))))
          (when status-win
            (with-selected-frame (window-frame status-win)
              (with-selected-window status-win
                (magit-status-internal project)))))))))

(global-set-key [remap other-window] #'my/other-window)

Based on my limited testing, that seems to work OK. You'd probably prefer the status buffer to be updated for events aside from other-window calls, but the code above gives you an idea of the how to update the status buffer. Note that if you rely on a hook that may get called a lot (e.g., buffer-list-update-hook), you'll probably want to design your solution so that the magit-toplevel calls (which call out to git) don't get executed every time the hook is run (e.g., first check buffer-file-name or the project name that is stored in a local variable when you visit the file, or ...).

2
  • wow I've just read your snippet to understand what you're doing and after checking the meaning of the variables and functions it's really awesome! I'm gonna try that and let you know! Nov 16, 2017 at 17:14
  • just tested it! thanks it's exactly what I wanted! Nov 16, 2017 at 17:19
1

I cannot offer more than the following rather general answer (copied straight from another question).

You can control how Magit selects a window to display a certain buffer using the option magit-display-buffer-function as described in Switching Buffers. Unfortunately this is a rather complicated matter and it is not possible to come up with a solution that works for everyone (for Magit buffers or in Emacs in general).

Well, may this:

Additionally you will have to update the status buffer whenever the current buffer changes in another window. I believe there is no build-in hook to do so, but you can use switch-buffer-functions for that purpose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.