2018-08-14 11:05:26 +02:00
package gui
2018-05-26 05:23:39 +02:00
import (
2018-07-21 07:51:18 +02:00
"fmt"
2018-05-26 05:23:39 +02:00
2018-07-21 07:51:18 +02:00
"github.com/jesseduffield/gocui"
2018-08-19 13:20:50 +02:00
"github.com/jesseduffield/lazygit/pkg/utils"
2018-08-16 07:53:53 +02:00
"github.com/spkg/bom"
2018-05-26 05:23:39 +02:00
)
2018-08-14 11:05:26 +02:00
func ( gui * Gui ) resetOrigin ( v * gocui . View ) error {
2019-04-25 21:37:19 +02:00
_ = v . SetCursor ( 0 , 0 )
2018-07-21 07:51:18 +02:00
return v . SetOrigin ( 0 , 0 )
2018-06-09 11:06:33 +02:00
}
2019-01-15 11:12:31 +02:00
func ( gui * Gui ) cleanString ( s string ) string {
2018-12-12 13:34:20 +02:00
output := string ( bom . Clean ( [ ] byte ( s ) ) )
2019-01-15 11:12:31 +02:00
return utils . NormalizeLinefeeds ( output )
}
2021-04-11 02:05:19 +02:00
func ( gui * Gui ) setViewContent ( v * gocui . View , s string ) {
2022-01-15 03:04:00 +02:00
v . SetContent ( gui . cleanString ( s ) )
2021-04-11 02:05:19 +02:00
}
2019-01-15 11:12:31 +02:00
// renderString resets the origin of a view and sets its content
2022-01-15 03:04:00 +02:00
func ( gui * Gui ) renderString ( view * gocui . View , s string ) error {
2021-04-04 16:31:52 +02:00
if err := view . SetOrigin ( 0 , 0 ) ; err != nil {
2020-08-16 10:25:08 +02:00
return err
}
2021-04-04 16:31:52 +02:00
if err := view . SetCursor ( 0 , 0 ) ; err != nil {
2020-08-16 10:25:08 +02:00
return err
}
2022-01-15 03:04:00 +02:00
gui . setViewContent ( view , s )
2020-08-16 10:25:08 +02:00
return nil
}
2019-02-25 13:11:35 +02:00
func ( gui * Gui ) currentViewName ( ) string {
currentView := gui . g . CurrentView ( )
2020-05-16 04:35:19 +02:00
if currentView == nil {
return ""
}
2018-08-14 11:05:26 +02:00
return currentView . Name ( )
}
2018-09-05 11:07:46 +02:00
2020-08-15 09:23:16 +02:00
func ( gui * Gui ) resizeCurrentPopupPanel ( ) error {
v := gui . g . CurrentView ( )
2020-08-18 14:41:14 +02:00
if v == nil {
return nil
}
2022-05-08 04:46:48 +02:00
if v == gui . Views . Menu {
gui . resizeMenu ( )
2022-05-08 05:14:24 +02:00
} else if v == gui . Views . Confirmation || v == gui . Views . Suggestions {
gui . resizeConfirmationPanel ( )
2022-05-08 04:46:48 +02:00
} else if gui . isPopupPanel ( v . Name ( ) ) {
2021-10-17 04:00:44 +02:00
return gui . resizePopupPanel ( v , v . Buffer ( ) )
2018-09-05 11:07:46 +02:00
}
2022-05-08 04:46:48 +02:00
2018-09-05 11:07:46 +02:00
return nil
}
2021-10-17 04:00:44 +02:00
func ( gui * Gui ) resizePopupPanel ( v * gocui . View , content string ) error {
2020-08-15 09:23:16 +02:00
x0 , y0 , x1 , y1 := gui . getConfirmationPanelDimensions ( v . Wrap , content )
_ , err := gui . g . SetView ( v . Name ( ) , x0 , y0 , x1 , y1 , 0 )
2018-09-05 11:07:46 +02:00
return err
}
2018-12-04 10:50:11 +02:00
2022-05-08 05:14:24 +02:00
func ( gui * Gui ) resizeMenu ( ) {
itemCount := gui . State . Contexts . Menu . GetList ( ) . Len ( )
offset := 3
panelWidth := gui . getConfirmationPanelWidth ( )
x0 , y0 , x1 , y1 := gui . getConfirmationPanelDimensionsForContentHeight ( panelWidth , itemCount + offset )
menuBottom := y1 - offset
_ , _ = gui . g . SetView ( gui . Views . Menu . Name ( ) , x0 , y0 , x1 , menuBottom , 0 )
tooltipTop := menuBottom + 1
tooltipHeight := gui . getMessageHeight ( true , gui . State . Contexts . Menu . GetSelected ( ) . Tooltip , panelWidth ) + 2 // plus 2 for the frame
_ , _ = gui . g . SetView ( gui . Views . Tooltip . Name ( ) , x0 , tooltipTop , x1 , tooltipTop + tooltipHeight - 1 , 0 )
}
func ( gui * Gui ) resizeConfirmationPanel ( ) {
suggestionsViewHeight := 0
if gui . Views . Suggestions . Visible {
suggestionsViewHeight = 11
}
panelWidth := gui . getConfirmationPanelWidth ( )
prompt := gui . Views . Confirmation . Buffer ( )
panelHeight := gui . getMessageHeight ( true , prompt , panelWidth ) + suggestionsViewHeight
x0 , y0 , x1 , y1 := gui . getConfirmationPanelDimensionsAux ( panelWidth , panelHeight )
confirmationViewBottom := y1 - suggestionsViewHeight
_ , _ = gui . g . SetView ( gui . Views . Confirmation . Name ( ) , x0 , y0 , x1 , confirmationViewBottom , 0 )
suggestionsViewTop := confirmationViewBottom + 1
_ , _ = gui . g . SetView ( gui . Views . Suggestions . Name ( ) , x0 , suggestionsViewTop , x1 , suggestionsViewTop + suggestionsViewHeight , 0 )
}
2020-08-23 02:50:27 +02:00
func ( gui * Gui ) globalOptionsMap ( ) map [ string ] string {
2022-01-16 05:46:53 +02:00
keybindingConfig := gui . c . UserConfig . Keybinding
2020-10-03 06:54:55 +02:00
2020-08-23 02:50:27 +02:00
return map [ string ] string {
2022-01-16 05:46:53 +02:00
fmt . Sprintf ( "%s/%s" , gui . getKeyDisplay ( keybindingConfig . Universal . ScrollUpMain ) , gui . getKeyDisplay ( keybindingConfig . Universal . ScrollDownMain ) ) : gui . c . Tr . LcScroll ,
fmt . Sprintf ( "%s %s %s %s" , gui . getKeyDisplay ( keybindingConfig . Universal . PrevBlock ) , gui . getKeyDisplay ( keybindingConfig . Universal . NextBlock ) , gui . getKeyDisplay ( keybindingConfig . Universal . PrevItem ) , gui . getKeyDisplay ( keybindingConfig . Universal . NextItem ) ) : gui . c . Tr . LcNavigate ,
gui . getKeyDisplay ( keybindingConfig . Universal . Return ) : gui . c . Tr . LcCancel ,
gui . getKeyDisplay ( keybindingConfig . Universal . Quit ) : gui . c . Tr . LcQuit ,
gui . getKeyDisplay ( keybindingConfig . Universal . OptionMenu ) : gui . c . Tr . LcMenu ,
fmt . Sprintf ( "%s-%s" , gui . getKeyDisplay ( keybindingConfig . Universal . JumpToBlock [ 0 ] ) , gui . getKeyDisplay ( keybindingConfig . Universal . JumpToBlock [ len ( keybindingConfig . Universal . JumpToBlock ) - 1 ] ) ) : gui . c . Tr . LcJump ,
fmt . Sprintf ( "%s/%s" , gui . getKeyDisplay ( keybindingConfig . Universal . ScrollLeft ) , gui . getKeyDisplay ( keybindingConfig . Universal . ScrollRight ) ) : gui . c . Tr . LcScrollLeftRight ,
2020-08-23 02:50:27 +02:00
}
2020-03-29 01:31:34 +02:00
}
2019-03-11 04:04:08 +02:00
func ( gui * Gui ) isPopupPanel ( viewName string ) bool {
2022-02-23 10:44:48 +02:00
return viewName == "commitMessage" || viewName == "confirmation" || viewName == "menu"
2019-03-11 04:04:08 +02:00
}
2019-02-25 13:11:35 +02:00
func ( gui * Gui ) popupPanelFocused ( ) bool {
2019-03-11 04:04:08 +02:00
return gui . isPopupPanel ( gui . currentViewName ( ) )
2019-02-25 13:11:35 +02:00
}
2019-11-10 07:20:35 +02:00
2020-05-18 14:00:07 +02:00
// secondaryViewFocused tells us whether it appears that the secondary view is focused. The view is actually never focused for real: we just swap the main and secondary views and then you're still focused on the main view so that we can give you access to all its keybindings for free. I will probably regret this design decision soon enough.
func ( gui * Gui ) secondaryViewFocused ( ) bool {
2020-10-07 23:01:04 +02:00
state := gui . State . Panels . LineByLine
return state != nil && state . SecondaryFocused
2020-05-18 14:00:07 +02:00
}
2020-08-17 13:58:30 +02:00
2020-08-19 11:31:58 +02:00
func ( gui * Gui ) onViewTabClick ( viewName string , tabIndex int ) error {
2022-03-26 05:33:39 +02:00
context := gui . State . ViewTabContextMap [ viewName ] [ tabIndex ] . Context
2020-08-19 11:31:58 +02:00
2022-01-16 05:46:53 +02:00
return gui . c . PushContext ( context )
2020-08-19 11:31:58 +02:00
}
2021-04-02 10:20:40 +02:00
func ( gui * Gui ) handleNextTab ( ) error {
2021-06-06 12:41:55 +02:00
v := getTabbedView ( gui )
2021-04-02 11:51:52 +02:00
if v == nil {
2021-04-02 10:20:40 +02:00
return nil
}
2020-08-19 11:31:58 +02:00
return gui . onViewTabClick (
v . Name ( ) ,
utils . ModuloWithWrap ( v . TabIndex + 1 , len ( v . Tabs ) ) ,
)
}
2021-04-02 10:20:40 +02:00
func ( gui * Gui ) handlePrevTab ( ) error {
2021-06-06 12:41:55 +02:00
v := getTabbedView ( gui )
2021-04-02 11:51:52 +02:00
if v == nil {
2021-04-02 10:20:40 +02:00
return nil
}
2020-08-19 11:31:58 +02:00
return gui . onViewTabClick (
v . Name ( ) ,
utils . ModuloWithWrap ( v . TabIndex - 1 , len ( v . Tabs ) ) ,
)
}
2020-10-01 23:56:14 +02:00
// this is the distance we will move the cursor when paging up or down in a view
func ( gui * Gui ) pageDelta ( view * gocui . View ) int {
_ , height := view . Size ( )
delta := height - 1
if delta == 0 {
return 1
}
return delta
}
2021-06-06 12:41:55 +02:00
func getTabbedView ( gui * Gui ) * gocui . View {
2021-06-15 19:58:43 +02:00
// It safe assumption that only static contexts have tabs
context := gui . currentStaticContext ( )
view , _ := gui . g . View ( context . GetViewName ( ) )
return view
2021-06-06 12:41:55 +02:00
}
2021-11-01 00:35:54 +02:00
func ( gui * Gui ) render ( ) {
2022-01-15 03:04:00 +02:00
gui . OnUIThread ( func ( ) error { return nil } )
2021-11-01 00:35:54 +02:00
}