Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add menu panel (cheatsheet) #234

Merged
merged 46 commits into from
Sep 9, 2018
Merged

WIP: Add menu panel (cheatsheet) #234

merged 46 commits into from
Sep 9, 2018

Conversation

dawidd6
Copy link
Collaborator

@dawidd6 dawidd6 commented Aug 28, 2018

My proposition is to add 2 new fields to Binding struct. One for human readable key (i don't know how to pretty print current Key field value) and the other one simply for description of what this key is responsible for. Then we can straightforwardly generate a cheatsheet on the fly. Possible in the future we'll be able to simply export this cheatsheet to separate file and for example put it on github as a replacement for manually written Keybindings.md.

Panel is currently set to maximum width and height, i think it's convenient.

Closes: #237

}

func (gui *Gui) handleHelpClose(g *gocui.Gui, v *gocui.View) error {
g.SetViewOnBottom(v.Name())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error return value of g.SetViewOnBottom is not checked

helpView, _ := g.SetView("help", 0, 0, maxX-1, maxY-2, 0)
helpView.Title = strings.Title(gui.Tr.SLocalize("help"))

gui.renderHelpOptions(g)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error return value of gui.renderHelpOptions is not checked

}
}

helpView.Write([]byte(content))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error return value of helpView.Write is not checked

helpView.Write([]byte(content))

g.Update(func(g *gocui.Gui) error {
g.SetViewOnTop("help")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error return value of g.SetViewOnTop is not checked


g.Update(func(g *gocui.Gui) error {
g.SetViewOnTop("help")
gui.switchFocus(g, v, helpView)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error return value of gui.switchFocus is not checked

@jesseduffield
Copy link
Owner

I like your proposition, but I think we could benefit from taking this one step further:

I've made a feature request denoting what I think would kill two birds with one stone:
#237

Effectively I want to have global keybindings displayed at the bottom at all times, and panel-specific keybindings available via a popup context menu that comes up when you press e.g. '?' or something similar. That way users don't even need to learn the keybindings, they can just use context menus. But the context menus will show the keybindings in each line aside the keybinding description, meaning if users want to use the popup as a cheatsheet they can too.

What are your thoughts on this?

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Aug 29, 2018

So if i understand right, you want to have ? key available globally but when for example focus is on commits panel then pressing ? will only display the keybindings for commits panel?

@jesseduffield
Copy link
Owner

yep :) It could be a better keybinding than '?' but yes that's the idea

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Aug 29, 2018

Also the cheatsheet should be selectable with space to execute specific handler?

@jesseduffield
Copy link
Owner

yep :)

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Aug 29, 2018

Okay will tinker with that.

@jesseduffield
Copy link
Owner

awesome lemme know if you have any questions

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Aug 29, 2018

@jesseduffield i'm currently thinking about size of the panel, do you have any desired dimensions?

@jesseduffield
Copy link
Owner

i think vertically it should just fit its contents, and horizontally maybe it should be 2/3 the screen width, as is currently the case with confirmation panels. If that is too wide we can shrink it down

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Aug 29, 2018

And could you tell me how to set it to fit its contents?

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Aug 29, 2018

Current state:

peek 2018-08-29 14-27

@codecov-io
Copy link

codecov-io commented Aug 29, 2018

Codecov Report

Merging #234 into master will increase coverage by 1.89%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #234      +/-   ##
==========================================
+ Coverage   84.82%   86.72%   +1.89%     
==========================================
  Files           9        9              
  Lines        1364     1559     +195     
==========================================
+ Hits         1157     1352     +195     
  Misses        206      206              
  Partials        1        1
Impacted Files Coverage Δ
pkg/i18n/dutch.go 100% <100%> (ø) ⬆️
pkg/i18n/polish.go 100% <100%> (ø) ⬆️
pkg/i18n/english.go 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5af03b6...63e4006. Read the comment docs.

@jesseduffield
Copy link
Owner

@dawidd6 looking good! There is a function in confirmation_panel.go called getMessageHeight which takes a string and a width and tells you how tall your view needs to be to contain it. So I'd recommend building up your key array and the display string first, then using that to determine the dimensions of your view, rather than making the view first and then populating it.

{ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate},
{ViewName: "", Key: '?', Modifier: gocui.ModNone, Handler: gui.handleHelp},
{ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, KeyReadable: "e", Description: "edit config"},
{ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, KeyReadable: "o", Description: "open config"},
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jesseduffield how do you feel about this? Should we indent the fields now since it is becoming long with 2 new fields?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep I think we should

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 1, 2018

@jesseduffield hey do we need space or other keys like this visible in help menu? I mean arrows, spaces or other special keys would be visible only at the bottom or do you want them to be also in help menu?

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 1, 2018

Test failing fix: #250

@jesseduffield
Copy link
Owner

@dawidd6 I would include the space, but not the arrow keys. Navigation keys should stay at the bottom, but any key that triggers an action like space etc should be in the menu.

The exception is global keys which should just be shown at the bottom. I guess there is no harm in putting pull/push in the context menu for the files panel or branches panel, but for now I think's simpler just to show panel-specific keybindings in the context menu.

How does that sound to you?

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 3, 2018

Okay. I will rebase this PR with latest master, include spaces and i think it will be all.

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 5, 2018

Also the generated cheatsheet currently looks like this:

Lazygit menu

Global

	P      push
	p      pull
	R      refresh

Status

	e      edit config file
	o      open config file
	u      check for update

Files

	c      commit changes
	C      commit changes using git editor
	space  toggle staged
	d      delete if untracked / checkout if tracked (aka go away)
	m      resolve merge conflicts
	e      edit file
	o      open file
	i      add to .gitignore
	r      refresh files
	S      stash files
	A      abort merge
	a      stage/unstage all
	t      add patch
	D      reset hard

Branches

	space  checkout
	c      checkout by name
	F      force checkout
	n      new branch
	d      delete branch
	D      delete branch (force)
	m      merge into currently checked out branch

Commits

	s      squash down
	r      rename commit
	R      rename commit with editor
	g      reset to this commit
	f      fixup commit

Stash

	space  apply
	g      pop
	d      drop

@jesseduffield
Copy link
Owner

@dawidd6 I was actually thinking we might make it even easier than that: perhaps we could use the tab key? But then, the tab key is already used for cycling through views and adding a newline in a commit message panel.

I was thinking 'm' (demoting the existing 'm' keybindings to shift+'m') but that's only easy to reach if you're using vim keybindings.

Enter is another good solution, but I think I still want to reserve that for focusing the main view (so that you can then scroll a diff with the arrow keys)

I would use 'h' but that's used for vim keybindings. What about 'g'? It's within reach for both regular keybindings and vim keybindings, and we'd only be demoting existing keybindings which don't semantically map well to 'g' in the first place (i.e. stash popping and resetting to a commit, which we can replace with 'x').

@jesseduffield
Copy link
Owner

btw awesome work on the automatically generating cheatsheet :)

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 5, 2018

Thanks for kind words 🎉.

Maybe better to not break currently established set of keybindings and use x for menu?

EDIT: changed it already anyway, can revert ofc.

@jesseduffield
Copy link
Owner

yep x sounds good

for _, binding := range bindings {
if key := gui.GetKey(binding); key != "" && (binding.ViewName == v.Name() || binding.ViewName == "") && binding.Description != "" {
if binding.ViewName != current {
content += "\n"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we move global keybindings to the bottom of the menu? I think that most people will just use the keybindings for these, and would want to see panel-specific menu items first

padWidth := gui.GetMaxKeyLength(bindings)

for _, binding := range bindings {
if key := gui.GetKey(binding); key != "" && (binding.ViewName == v.Name() || binding.ViewName == "") && binding.Description != "" {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor gripe but we can flatten this a bit by saying

key := gui.GetKey(binding)
if key == "" || binding.Description == "" || (binding.ViewName != v.Name() && binding.ViewName != "") {
    continue        
}
...

panel keybindings are now on top and
global keybindings are below separated with empty newline
this is fmt number x+1
@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 7, 2018

Done @jesseduffield

Oh man, merge conflicts again.

@glvr182
Copy link
Contributor

glvr182 commented Sep 8, 2018

@dawidd6 How far are you on the PR, soon i'm going to rework the GUI package. I'll start on this when you're done with this PR. No rush just curious.

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 8, 2018

@glvr182 well, i would say it is done already. Waiting for further review.

@glvr182
Copy link
Contributor

glvr182 commented Sep 8, 2018

@dawidd6 A perfect, would also love to see this all in action, its really usefull! I guess we have to wait for @jesseduffield

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 8, 2018

@glvr182 what kind of rework are you planning?

@glvr182
Copy link
Contributor

glvr182 commented Sep 8, 2018

@dawidd6 Well i talked to @jesseduffield shortly about it as well and bascly, rewriting functions that can be made smarter, remove double code, better error handling / logging, dont pass useless parameters to functions, improve readability, and comments + formatting

@glvr182
Copy link
Contributor

glvr182 commented Sep 8, 2018

so yea it's gonna be a big update

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 8, 2018

I agree, after spending some time in the codebase i can tell it is in need for some rework.

@glvr182
Copy link
Contributor

glvr182 commented Sep 8, 2018

@dawidd6 Ill start with it as soon as i can, if you have some ideas about possible changes you can just send me a message or if you want implement them in the branch ill be working in (to be created)

@jesseduffield
Copy link
Owner

@dawidd6 are you okay to look at these merge conflicts?

@dawidd6
Copy link
Collaborator Author

dawidd6 commented Sep 9, 2018

@jesseduffield done, i think it's alright.

@jesseduffield
Copy link
Owner

LGTM, fantastic work man :)

@jesseduffield jesseduffield merged commit f8ab4f4 into jesseduffield:master Sep 9, 2018
@dawidd6 dawidd6 deleted the feature/help branch September 10, 2018 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants