mirror of
				https://github.com/jesseduffield/lazygit.git
				synced 2025-10-30 23:57:43 +02:00 
			
		
		
		
	fix issue caused by opening a menu over a prompt
This commit is contained in:
		| @@ -79,9 +79,10 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error { | |||||||
|  |  | ||||||
| 	gui.State.ContextManager.Lock() | 	gui.State.ContextManager.Lock() | ||||||
|  |  | ||||||
| 	// push onto stack | 	if len(gui.State.ContextManager.ContextStack) == 0 { | ||||||
|  | 		gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c) | ||||||
|  | 	} else if c.GetKind() == types.SIDE_CONTEXT { | ||||||
| 		// if we are switching to a side context, remove all other contexts in the stack | 		// if we are switching to a side context, remove all other contexts in the stack | ||||||
| 	if c.GetKind() == types.SIDE_CONTEXT { |  | ||||||
| 		for _, stackContext := range gui.State.ContextManager.ContextStack { | 		for _, stackContext := range gui.State.ContextManager.ContextStack { | ||||||
| 			if stackContext.GetKey() != c.GetKey() { | 			if stackContext.GetKey() != c.GetKey() { | ||||||
| 				if err := gui.deactivateContext(stackContext); err != nil { | 				if err := gui.deactivateContext(stackContext); err != nil { | ||||||
| @@ -91,13 +92,26 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		gui.State.ContextManager.ContextStack = []types.Context{c} | 		gui.State.ContextManager.ContextStack = []types.Context{c} | ||||||
| 	} else if len(gui.State.ContextManager.ContextStack) == 0 || gui.currentContextWithoutLock().GetKey() != c.GetKey() { | 	} else { | ||||||
| 		// Do not append if the one at the end is the same context (e.g. opening a menu from a menu) | 		topContext := gui.currentContextWithoutLock() | ||||||
| 		// In that case we'll just close the menu entirely when the user hits escape. |  | ||||||
|  | 		// if we're pushing the same context on, we do nothing. | ||||||
|  | 		if topContext.GetKey() != c.GetKey() { | ||||||
|  | 			// if top one is a temporary popup, we remove it. Ideally you'd be able to | ||||||
|  | 			// escape back to previous temporary popups, but because we're currently reusing | ||||||
|  | 			// views for this, you might not be able to get back to where you previously were. | ||||||
|  | 			if topContext.GetKind() == types.TEMPORARY_POPUP { | ||||||
|  | 				if err := gui.deactivateContext(topContext); err != nil { | ||||||
|  | 					gui.State.ContextManager.Unlock() | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				_, gui.State.ContextManager.ContextStack = slices.Pop(gui.State.ContextManager.ContextStack) | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 		// TODO: think about other exceptional cases |  | ||||||
| 			gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c) | 			gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	gui.State.ContextManager.Unlock() | 	gui.State.ContextManager.Unlock() | ||||||
|  |  | ||||||
| @@ -111,7 +125,7 @@ func (gui *Gui) pushContextWithView(viewName string) error { | |||||||
| 	return gui.c.PushContext(gui.State.ViewContextMap.Get(viewName)) | 	return gui.c.PushContext(gui.State.ViewContextMap.Get(viewName)) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (gui *Gui) returnFromContext() error { | func (gui *Gui) popContext() error { | ||||||
| 	gui.State.ContextManager.Lock() | 	gui.State.ContextManager.Lock() | ||||||
|  |  | ||||||
| 	if len(gui.State.ContextManager.ContextStack) == 1 { | 	if len(gui.State.ContextManager.ContextStack) == 1 { | ||||||
| @@ -120,12 +134,10 @@ func (gui *Gui) returnFromContext() error { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	n := len(gui.State.ContextManager.ContextStack) - 1 | 	var currentContext types.Context | ||||||
|  | 	currentContext, gui.State.ContextManager.ContextStack = slices.Pop(gui.State.ContextManager.ContextStack) | ||||||
|  |  | ||||||
| 	currentContext := gui.State.ContextManager.ContextStack[n] | 	newContext := gui.State.ContextManager.ContextStack[len(gui.State.ContextManager.ContextStack)-1] | ||||||
| 	newContext := gui.State.ContextManager.ContextStack[n-1] |  | ||||||
|  |  | ||||||
| 	gui.State.ContextManager.ContextStack = gui.State.ContextManager.ContextStack[:n] |  | ||||||
|  |  | ||||||
| 	gui.g.SetCurrentContext(string(newContext.GetKey())) | 	gui.g.SetCurrentContext(string(newContext.GetKey())) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ func NewMenuContext( | |||||||
| 			Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ | 			Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ | ||||||
| 				ViewName:        "menu", | 				ViewName:        "menu", | ||||||
| 				Key:             "menu", | 				Key:             "menu", | ||||||
| 				Kind:            types.PERSISTENT_POPUP, | 				Kind:            types.TEMPORARY_POPUP, | ||||||
| 				OnGetOptionsMap: getOptionsMap, | 				OnGetOptionsMap: getOptionsMap, | ||||||
| 				Focusable:       true, | 				Focusable:       true, | ||||||
| 			}), ContextCallbackOpts{ | 			}), ContextCallbackOpts{ | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ func (self *guiCommon) PushContext(context types.Context, opts ...types.OnFocusO | |||||||
| } | } | ||||||
|  |  | ||||||
| func (self *guiCommon) PopContext() error { | func (self *guiCommon) PopContext() error { | ||||||
| 	return self.gui.returnFromContext() | 	return self.gui.popContext() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (self *guiCommon) CurrentContext() types.Context { | func (self *guiCommon) CurrentContext() types.Context { | ||||||
|   | |||||||
| @@ -8,12 +8,22 @@ import ( | |||||||
| type ContextKind int | type ContextKind int | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|  | 	// this is your files, branches, commits, contexts etc. They're all on the left hand side | ||||||
|  | 	// and you can cycle through them. | ||||||
| 	SIDE_CONTEXT ContextKind = iota | 	SIDE_CONTEXT ContextKind = iota | ||||||
|  | 	// This is either the left or right 'main' contexts that appear to the right of the side contexts | ||||||
| 	MAIN_CONTEXT | 	MAIN_CONTEXT | ||||||
| 	TEMPORARY_POPUP | 	// A persistent popup is one that has its own identity e.g. the commit message context. | ||||||
|  | 	// When you open a popup over it, we'll let you return to it upon pressing escape | ||||||
| 	PERSISTENT_POPUP | 	PERSISTENT_POPUP | ||||||
|  | 	// A temporary popup is one that could be used for various things (e.g. a generic menu or confirmation popup). | ||||||
|  | 	// Because we re-use these contexts, they're temporary in that you can't return to them after you've switched from them | ||||||
|  | 	// to some other context, because the context you switched to might actually be the same context but rendering different content. | ||||||
|  | 	// We should really be able to spawn new contexts for menus/prompts so that we can actually return to old ones. | ||||||
|  | 	TEMPORARY_POPUP | ||||||
|  | 	// This contains the command log, underneath the main contexts. | ||||||
| 	EXTRAS_CONTEXT | 	EXTRAS_CONTEXT | ||||||
| 	// only used by the one global context | 	// only used by the one global context, purely for the sake of defining keybindings globally | ||||||
| 	GLOBAL_CONTEXT | 	GLOBAL_CONTEXT | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user