mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-13 11:50:28 +02:00
allow opening lazygit to a specific panel
This commit is contained in:
parent
36aa01c3ac
commit
b1e4968d0b
35
main.go
35
main.go
@ -7,12 +7,14 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/integrii/flaggy"
|
"github.com/integrii/flaggy"
|
||||||
"github.com/jesseduffield/lazygit/pkg/app"
|
"github.com/jesseduffield/lazygit/pkg/app"
|
||||||
"github.com/jesseduffield/lazygit/pkg/app/daemon"
|
"github.com/jesseduffield/lazygit/pkg/app/daemon"
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
"github.com/jesseduffield/lazygit/pkg/env"
|
"github.com/jesseduffield/lazygit/pkg/env"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/logs"
|
"github.com/jesseduffield/lazygit/pkg/logs"
|
||||||
yaml "github.com/jesseduffield/yaml"
|
yaml "github.com/jesseduffield/yaml"
|
||||||
)
|
)
|
||||||
@ -33,9 +35,8 @@ func main() {
|
|||||||
filterPath := ""
|
filterPath := ""
|
||||||
flaggy.String(&filterPath, "f", "filter", "Path to filter on in `git log -- <path>`. When in filter mode, the commits, reflog, and stash are filtered based on the given path, and some operations are restricted")
|
flaggy.String(&filterPath, "f", "filter", "Path to filter on in `git log -- <path>`. When in filter mode, the commits, reflog, and stash are filtered based on the given path, and some operations are restricted")
|
||||||
|
|
||||||
dump := ""
|
gitArg := ""
|
||||||
flaggy.AddPositionalValue(&dump, "gitargs", 1, false, "Todo file")
|
flaggy.AddPositionalValue(&gitArg, "git-arg", 1, false, "Panel to focus upon opening lazygit. Accepted values (based on git terminology): status, branch, log, stash. Ignored if --filter arg is passed.")
|
||||||
flaggy.DefaultParser.PositionalFlags[0].Hidden = true
|
|
||||||
|
|
||||||
versionFlag := false
|
versionFlag := false
|
||||||
flaggy.Bool(&versionFlag, "v", "version", "Print the current version")
|
flaggy.Bool(&versionFlag, "v", "version", "Print the current version")
|
||||||
@ -148,5 +149,31 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Run(appConfig, common, filterPath)
|
parsedGitArg := parseGitArg(gitArg)
|
||||||
|
|
||||||
|
app.Run(appConfig, common, types.NewStartArgs(filterPath, parsedGitArg))
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseGitArg(gitArg string) types.GitArg {
|
||||||
|
typedArg := types.GitArg(gitArg)
|
||||||
|
|
||||||
|
// using switch so that linter catches when a new git arg value is defined but not handled here
|
||||||
|
switch typedArg {
|
||||||
|
case types.GitArgNone, types.GitArgStatus, types.GitArgBranch, types.GitArgLog, types.GitArgStash:
|
||||||
|
return typedArg
|
||||||
|
}
|
||||||
|
|
||||||
|
permittedValues := []string{
|
||||||
|
string(types.GitArgStatus),
|
||||||
|
string(types.GitArgBranch),
|
||||||
|
string(types.GitArgLog),
|
||||||
|
string(types.GitArgStash),
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Fatalf("Invalid git arg value: '%s'. Must be one of the following values: %s. e.g. 'lazygit status'. See 'lazygit --help'.",
|
||||||
|
gitArg,
|
||||||
|
strings.Join(permittedValues, ", "),
|
||||||
|
)
|
||||||
|
|
||||||
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/constants"
|
"github.com/jesseduffield/lazygit/pkg/constants"
|
||||||
"github.com/jesseduffield/lazygit/pkg/env"
|
"github.com/jesseduffield/lazygit/pkg/env"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui"
|
"github.com/jesseduffield/lazygit/pkg/gui"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||||
"github.com/jesseduffield/lazygit/pkg/updates"
|
"github.com/jesseduffield/lazygit/pkg/updates"
|
||||||
)
|
)
|
||||||
@ -37,11 +38,11 @@ type App struct {
|
|||||||
Updater *updates.Updater // may only need this on the Gui
|
Updater *updates.Updater // may only need this on the Gui
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run(config config.AppConfigurer, common *common.Common, filterPath string) {
|
func Run(config config.AppConfigurer, common *common.Common, startArgs types.StartArgs) {
|
||||||
app, err := NewApp(config, common)
|
app, err := NewApp(config, common)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = app.Run(filterPath)
|
err = app.Run(startArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -203,8 +204,8 @@ func (app *App) setupRepo() (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) Run(filterPath string) error {
|
func (app *App) Run(startArgs types.StartArgs) error {
|
||||||
err := app.Gui.RunAndHandleError(filterPath)
|
err := app.Gui.RunAndHandleError(startArgs)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ type guiMutexes struct {
|
|||||||
PopupMutex *sync.Mutex
|
PopupMutex *sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) onNewRepo(filterPath string, reuseState bool) error {
|
func (gui *Gui) onNewRepo(startArgs types.StartArgs, reuseState bool) error {
|
||||||
var err error
|
var err error
|
||||||
gui.git, err = commands.NewGitCommand(
|
gui.git, err = commands.NewGitCommand(
|
||||||
gui.Common,
|
gui.Common,
|
||||||
@ -261,7 +261,7 @@ func (gui *Gui) onNewRepo(filterPath string, reuseState bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.resetState(filterPath, reuseState)
|
gui.resetState(startArgs, reuseState)
|
||||||
|
|
||||||
gui.resetControllers()
|
gui.resetControllers()
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ func (gui *Gui) onNewRepo(filterPath string, reuseState bool) error {
|
|||||||
// it gets a bit confusing to land back in the status panel when visiting a repo
|
// it gets a bit confusing to land back in the status panel when visiting a repo
|
||||||
// you've already switched from. There's no doubt some easy way to make the UX
|
// you've already switched from. There's no doubt some easy way to make the UX
|
||||||
// optimal for all cases but I'm too lazy to think about what that is right now
|
// optimal for all cases but I'm too lazy to think about what that is right now
|
||||||
func (gui *Gui) resetState(filterPath string, reuseState bool) {
|
func (gui *Gui) resetState(startArgs types.StartArgs, reuseState bool) {
|
||||||
currentDir, err := os.Getwd()
|
currentDir, err := os.Getwd()
|
||||||
|
|
||||||
if reuseState {
|
if reuseState {
|
||||||
@ -306,12 +306,8 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
|
|||||||
|
|
||||||
contextTree := gui.contextTree()
|
contextTree := gui.contextTree()
|
||||||
|
|
||||||
screenMode := SCREEN_NORMAL
|
initialContext := initialContext(contextTree, startArgs)
|
||||||
var initialContext types.IListContext = contextTree.Files
|
initialScreenMode := initialScreenMode(startArgs)
|
||||||
if filterPath != "" {
|
|
||||||
screenMode = SCREEN_HALF
|
|
||||||
initialContext = contextTree.LocalCommits
|
|
||||||
}
|
|
||||||
|
|
||||||
viewContextMap := context.NewViewContextMap()
|
viewContextMap := context.NewViewContextMap()
|
||||||
for viewName, context := range initialViewContextMapping(contextTree) {
|
for viewName, context := range initialViewContextMapping(contextTree) {
|
||||||
@ -338,13 +334,13 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
|
|||||||
},
|
},
|
||||||
Ptmx: nil,
|
Ptmx: nil,
|
||||||
Modes: &types.Modes{
|
Modes: &types.Modes{
|
||||||
Filtering: filtering.New(filterPath),
|
Filtering: filtering.New(startArgs.FilterPath),
|
||||||
CherryPicking: cherrypicking.New(),
|
CherryPicking: cherrypicking.New(),
|
||||||
Diffing: diffing.New(),
|
Diffing: diffing.New(),
|
||||||
},
|
},
|
||||||
ViewContextMap: viewContextMap,
|
ViewContextMap: viewContextMap,
|
||||||
ViewTabContextMap: gui.initialViewTabContextMap(contextTree),
|
ViewTabContextMap: gui.initialViewTabContextMap(contextTree),
|
||||||
ScreenMode: screenMode,
|
ScreenMode: initialScreenMode,
|
||||||
// TODO: put contexts in the context manager
|
// TODO: put contexts in the context manager
|
||||||
ContextManager: NewContextManager(initialContext),
|
ContextManager: NewContextManager(initialContext),
|
||||||
Contexts: contextTree,
|
Contexts: contextTree,
|
||||||
@ -355,6 +351,37 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
|
|||||||
gui.RepoStateMap[Repo(currentDir)] = gui.State
|
gui.RepoStateMap[Repo(currentDir)] = gui.State
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initialScreenMode(startArgs types.StartArgs) WindowMaximisation {
|
||||||
|
if startArgs.FilterPath != "" || startArgs.GitArg != types.GitArgNone {
|
||||||
|
return SCREEN_HALF
|
||||||
|
} else {
|
||||||
|
return SCREEN_NORMAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initialContext(contextTree *context.ContextTree, startArgs types.StartArgs) types.IListContext {
|
||||||
|
var initialContext types.IListContext = contextTree.Files
|
||||||
|
|
||||||
|
if startArgs.FilterPath != "" {
|
||||||
|
initialContext = contextTree.LocalCommits
|
||||||
|
} else if startArgs.GitArg != types.GitArgNone {
|
||||||
|
switch startArgs.GitArg {
|
||||||
|
case types.GitArgStatus:
|
||||||
|
initialContext = contextTree.Files
|
||||||
|
case types.GitArgBranch:
|
||||||
|
initialContext = contextTree.Branches
|
||||||
|
case types.GitArgLog:
|
||||||
|
initialContext = contextTree.LocalCommits
|
||||||
|
case types.GitArgStash:
|
||||||
|
initialContext = contextTree.Stash
|
||||||
|
default:
|
||||||
|
panic("unhandled git arg")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialContext
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) syncViewContexts() {
|
func (gui *Gui) syncViewContexts() {
|
||||||
for viewName, context := range gui.State.ViewContextMap.Entries() {
|
for viewName, context := range gui.State.ViewContextMap.Entries() {
|
||||||
view, err := gui.g.View(viewName)
|
view, err := gui.g.View(viewName)
|
||||||
@ -506,7 +533,7 @@ func (gui *Gui) initialViewTabContextMap(contextTree *context.ContextTree) map[s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run: setup the gui with keybindings and start the mainloop
|
// Run: setup the gui with keybindings and start the mainloop
|
||||||
func (gui *Gui) Run(filterPath string) error {
|
func (gui *Gui) Run(startArgs types.StartArgs) error {
|
||||||
g, err := gui.initGocui()
|
g, err := gui.initGocui()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -559,7 +586,7 @@ func (gui *Gui) Run(filterPath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// onNewRepo must be called after g.SetManager because SetManager deletes keybindings
|
// onNewRepo must be called after g.SetManager because SetManager deletes keybindings
|
||||||
if err := gui.onNewRepo(filterPath, false); err != nil {
|
if err := gui.onNewRepo(startArgs, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,10 +619,10 @@ func (gui *Gui) Run(filterPath string) error {
|
|||||||
return gui.g.MainLoop()
|
return gui.g.MainLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) RunAndHandleError(filterPath string) error {
|
func (gui *Gui) RunAndHandleError(startArgs types.StartArgs) error {
|
||||||
gui.stopChan = make(chan struct{})
|
gui.stopChan = make(chan struct{})
|
||||||
return utils.SafeWithError(func() error {
|
return utils.SafeWithError(func() error {
|
||||||
if err := gui.Run(filterPath); err != nil {
|
if err := gui.Run(startArgs); err != nil {
|
||||||
for _, manager := range gui.viewBufferManagerMap {
|
for _, manager := range gui.viewBufferManagerMap {
|
||||||
manager.Close()
|
manager.Close()
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ func (gui *Gui) dispatchSwitchToRepo(path string, reuse bool) error {
|
|||||||
gui.Mutexes.RefreshingFilesMutex.Lock()
|
gui.Mutexes.RefreshingFilesMutex.Lock()
|
||||||
defer gui.Mutexes.RefreshingFilesMutex.Unlock()
|
defer gui.Mutexes.RefreshingFilesMutex.Unlock()
|
||||||
|
|
||||||
return gui.onNewRepo("", reuse)
|
return gui.onNewRepo(types.StartArgs{}, reuse)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateRecentRepoList registers the fact that we opened lazygit in this repo,
|
// updateRecentRepoList registers the fact that we opened lazygit in this repo,
|
||||||
|
26
pkg/gui/types/main_args.go
Normal file
26
pkg/gui/types/main_args.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
// StartArgs is the struct that represents some things we want to do on program start
|
||||||
|
type StartArgs struct {
|
||||||
|
// FilterPath determines which path we're going to filter on so that we only see commits from that file.
|
||||||
|
FilterPath string
|
||||||
|
// GitArg determines what context we open in
|
||||||
|
GitArg GitArg
|
||||||
|
}
|
||||||
|
|
||||||
|
type GitArg string
|
||||||
|
|
||||||
|
const (
|
||||||
|
GitArgNone GitArg = ""
|
||||||
|
GitArgStatus GitArg = "status"
|
||||||
|
GitArgBranch GitArg = "branch"
|
||||||
|
GitArgLog GitArg = "log"
|
||||||
|
GitArgStash GitArg = "stash"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewStartArgs(filterPath string, gitArg GitArg) StartArgs {
|
||||||
|
return StartArgs{
|
||||||
|
FilterPath: filterPath,
|
||||||
|
GitArg: gitArg,
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
blah
|
1
test/integration/gitArg/expected/repo/.git_keep/HEAD
Normal file
1
test/integration/gitArg/expected/repo/.git_keep/HEAD
Normal file
@ -0,0 +1 @@
|
|||||||
|
ref: refs/heads/master
|
10
test/integration/gitArg/expected/repo/.git_keep/config
Normal file
10
test/integration/gitArg/expected/repo/.git_keep/config
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[core]
|
||||||
|
repositoryformatversion = 0
|
||||||
|
filemode = true
|
||||||
|
bare = false
|
||||||
|
logallrefupdates = true
|
||||||
|
ignorecase = true
|
||||||
|
precomposeunicode = true
|
||||||
|
[user]
|
||||||
|
email = CI@example.com
|
||||||
|
name = CI
|
@ -0,0 +1 @@
|
|||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
BIN
test/integration/gitArg/expected/repo/.git_keep/index
Normal file
BIN
test/integration/gitArg/expected/repo/.git_keep/index
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
|||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
||||||
|
.DS_Store
|
@ -0,0 +1,3 @@
|
|||||||
|
0000000000000000000000000000000000000000 45fe0608335366a31a1ad6dacbdcc6b17d31a5b6 CI <CI@example.com> 1654768290 +1000 commit (initial): blah
|
||||||
|
45fe0608335366a31a1ad6dacbdcc6b17d31a5b6 45fe0608335366a31a1ad6dacbdcc6b17d31a5b6 CI <CI@example.com> 1654768290 +1000 checkout: moving from master to other
|
||||||
|
45fe0608335366a31a1ad6dacbdcc6b17d31a5b6 45fe0608335366a31a1ad6dacbdcc6b17d31a5b6 CI <CI@example.com> 1654768291 +1000 checkout: moving from other to master
|
@ -0,0 +1 @@
|
|||||||
|
0000000000000000000000000000000000000000 45fe0608335366a31a1ad6dacbdcc6b17d31a5b6 CI <CI@example.com> 1654768290 +1000 commit (initial): blah
|
@ -0,0 +1 @@
|
|||||||
|
0000000000000000000000000000000000000000 45fe0608335366a31a1ad6dacbdcc6b17d31a5b6 CI <CI@example.com> 1654768290 +1000 branch: Created from HEAD
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
45fe0608335366a31a1ad6dacbdcc6b17d31a5b6
|
@ -0,0 +1 @@
|
|||||||
|
45fe0608335366a31a1ad6dacbdcc6b17d31a5b6
|
1
test/integration/gitArg/recording.json
Normal file
1
test/integration/gitArg/recording.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"KeyEvents":[{"Timestamp":620,"Mod":0,"Key":258,"Ch":0},{"Timestamp":995,"Mod":0,"Key":256,"Ch":32},{"Timestamp":1865,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":272,"Height":74}]}
|
14
test/integration/gitArg/setup.sh
Normal file
14
test/integration/gitArg/setup.sh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd $1
|
||||||
|
|
||||||
|
git init
|
||||||
|
|
||||||
|
git config user.email "CI@example.com"
|
||||||
|
git config user.name "CI"
|
||||||
|
|
||||||
|
git commit --allow-empty -m "blah"
|
||||||
|
|
||||||
|
git checkout -b other
|
5
test/integration/gitArg/test.json
Normal file
5
test/integration/gitArg/test.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"description": "Open lazygit to the branches panel",
|
||||||
|
"speed": 10,
|
||||||
|
"extraCmdArgs": "branch"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user