2020-08-16 05:58:29 +02:00
|
|
|
package gui
|
|
|
|
|
2022-02-05 05:42:56 +02:00
|
|
|
import (
|
2022-06-13 03:01:26 +02:00
|
|
|
"fmt"
|
|
|
|
|
2022-10-03 05:31:40 +02:00
|
|
|
"github.com/jesseduffield/gocui"
|
2022-06-13 03:01:26 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
2022-02-05 05:42:56 +02:00
|
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
2022-06-13 03:01:26 +02:00
|
|
|
"github.com/samber/lo"
|
2022-02-05 05:42:56 +02:00
|
|
|
)
|
2021-04-04 17:10:23 +02:00
|
|
|
|
2020-08-16 05:58:29 +02:00
|
|
|
// A window refers to a place on the screen which can hold one or more views.
|
|
|
|
// A view is a box that renders content, and within a window only one view will
|
|
|
|
// appear at a time. When a view appears within a window, it occupies the whole
|
|
|
|
// space. Right now most windows are 1:1 with views, except for commitFiles which
|
2020-08-23 02:13:56 +02:00
|
|
|
// is a view that moves between windows
|
2020-08-16 05:58:29 +02:00
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
func (gui *Gui) initialWindowViewNameMap(contextTree *context.ContextTree) map[string]string {
|
|
|
|
result := map[string]string{}
|
|
|
|
|
|
|
|
for _, context := range contextTree.Flatten() {
|
|
|
|
result[context.GetWindowName()] = context.GetViewName()
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2020-08-16 05:58:29 +02:00
|
|
|
func (gui *Gui) getViewNameForWindow(window string) string {
|
|
|
|
viewName, ok := gui.State.WindowViewNameMap[window]
|
|
|
|
if !ok {
|
2022-06-13 03:01:26 +02:00
|
|
|
panic(fmt.Sprintf("Viewname not found for window: %s", window))
|
2020-08-16 05:58:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return viewName
|
|
|
|
}
|
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
func (gui *Gui) getContextForWindow(window string) types.Context {
|
|
|
|
viewName := gui.getViewNameForWindow(window)
|
|
|
|
|
|
|
|
context, ok := gui.contextForView(viewName)
|
|
|
|
if !ok {
|
|
|
|
panic("TODO: fix this")
|
2020-08-16 05:58:29 +02:00
|
|
|
}
|
|
|
|
|
2022-06-13 03:01:26 +02:00
|
|
|
return context
|
|
|
|
}
|
|
|
|
|
|
|
|
// for now all we actually care about is the context's view so we're storing that
|
|
|
|
func (gui *Gui) setWindowContext(c types.Context) {
|
2022-03-26 05:23:47 +02:00
|
|
|
if c.IsTransient() {
|
|
|
|
gui.resetWindowContext(c)
|
|
|
|
}
|
|
|
|
|
2022-02-05 05:42:56 +02:00
|
|
|
gui.State.WindowViewNameMap[c.GetWindowName()] = c.GetViewName()
|
2020-08-16 05:58:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) currentWindow() string {
|
2022-02-05 05:42:56 +02:00
|
|
|
return gui.currentContext().GetWindowName()
|
2020-08-16 05:58:29 +02:00
|
|
|
}
|
2020-08-21 12:08:42 +02:00
|
|
|
|
2022-03-26 05:23:47 +02:00
|
|
|
// assumes the context's windowName has been set to the new window if necessary
|
2022-02-05 05:42:56 +02:00
|
|
|
func (gui *Gui) resetWindowContext(c types.Context) {
|
2022-03-26 05:23:47 +02:00
|
|
|
for windowName, viewName := range gui.State.WindowViewNameMap {
|
|
|
|
if viewName == c.GetViewName() && windowName != c.GetWindowName() {
|
2022-06-13 03:01:26 +02:00
|
|
|
for _, context := range gui.State.Contexts.Flatten() {
|
|
|
|
if context.GetKey() != c.GetKey() && context.GetWindowName() == windowName {
|
|
|
|
gui.State.WindowViewNameMap[windowName] = context.GetViewName()
|
|
|
|
}
|
|
|
|
}
|
2022-03-26 05:23:47 +02:00
|
|
|
}
|
2022-03-24 13:07:30 +02:00
|
|
|
}
|
2020-08-21 12:08:42 +02:00
|
|
|
}
|
2022-06-13 03:01:26 +02:00
|
|
|
|
2022-10-03 05:31:40 +02:00
|
|
|
// moves given context's view to the top of the window and returns
|
|
|
|
// true if the view was not already on top.
|
|
|
|
func (gui *Gui) moveToTopOfWindow(context types.Context) bool {
|
2022-06-13 03:01:26 +02:00
|
|
|
view := context.GetView()
|
|
|
|
if view == nil {
|
2022-10-03 05:31:40 +02:00
|
|
|
return false
|
2022-06-13 03:01:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
window := context.GetWindowName()
|
|
|
|
|
2022-10-03 05:31:40 +02:00
|
|
|
topView := gui.topViewInWindow(window)
|
|
|
|
|
|
|
|
if view.Name() == topView.Name() {
|
|
|
|
return false
|
|
|
|
} else {
|
|
|
|
if err := gui.g.SetViewOnTopOf(view.Name(), topView.Name()); err != nil {
|
|
|
|
gui.Log.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) topViewInWindow(windowName string) *gocui.View {
|
2022-06-13 03:01:26 +02:00
|
|
|
// now I need to find all views in that same window, via contexts. And I guess then I need to find the index of the highest view in that list.
|
2022-10-03 05:31:40 +02:00
|
|
|
viewNamesInWindow := gui.viewNamesInWindow(windowName)
|
2022-06-13 03:01:26 +02:00
|
|
|
|
|
|
|
// The views list is ordered highest-last, so we're grabbing the last view of the window
|
2022-10-03 05:31:40 +02:00
|
|
|
var topView *gocui.View
|
2022-06-13 03:01:26 +02:00
|
|
|
for _, currentView := range gui.g.Views() {
|
|
|
|
if lo.Contains(viewNamesInWindow, currentView.Name()) {
|
|
|
|
topView = currentView
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-03 05:31:40 +02:00
|
|
|
return topView
|
2022-06-13 03:01:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) viewNamesInWindow(windowName string) []string {
|
|
|
|
result := []string{}
|
|
|
|
for _, context := range gui.State.Contexts.Flatten() {
|
|
|
|
if context.GetWindowName() == windowName {
|
|
|
|
result = append(result, context.GetViewName())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|