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
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 ...).
-
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
-
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.