mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-03-17 21:18:31 +02:00
test
type safe view access
This commit is contained in:
parent
5b0958a2fd
commit
eaa2d792e1
@ -30,13 +30,13 @@ func (gui *Gui) handleBranchSelect() error {
|
||||
var task updateTask
|
||||
branch := gui.getSelectedBranch()
|
||||
if branch == nil {
|
||||
task = gui.createRenderStringTask(gui.Tr.NoBranchesThisRepo)
|
||||
task = NewRenderStringTask(gui.Tr.NoBranchesThisRepo)
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.GetBranchGraphCmdStr(branch.Name),
|
||||
)
|
||||
|
||||
task = gui.createRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
@ -473,7 +473,7 @@ func (gui *Gui) currentBranch() *models.Branch {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleNewBranchOffCurrentItem() error {
|
||||
context := gui.currentSideContext()
|
||||
context := gui.currentSideListContext()
|
||||
|
||||
item, ok := context.GetSelectedItem()
|
||||
if !ok {
|
||||
|
@ -24,7 +24,7 @@ func (gui *Gui) handleCopyCommit() error {
|
||||
}
|
||||
|
||||
// get currently selected commit, add the sha to state.
|
||||
context := gui.currentSideContext()
|
||||
context := gui.currentSideListContext()
|
||||
if context == nil {
|
||||
return nil
|
||||
}
|
||||
@ -63,7 +63,7 @@ func (gui *Gui) cherryPickedCommitShaMap() map[string]bool {
|
||||
}
|
||||
|
||||
func (gui *Gui) commitsListForContext() []*models.Commit {
|
||||
context := gui.currentSideContext()
|
||||
context := gui.currentSideListContext()
|
||||
if context == nil {
|
||||
return nil
|
||||
}
|
||||
@ -104,7 +104,7 @@ func (gui *Gui) handleCopyCommitRange() error {
|
||||
}
|
||||
|
||||
// get currently selected commit, add the sha to state.
|
||||
context := gui.currentSideContext()
|
||||
context := gui.currentSideListContext()
|
||||
if context == nil {
|
||||
return nil
|
||||
}
|
||||
@ -169,7 +169,7 @@ func (gui *Gui) exitCherryPickingMode() error {
|
||||
return gui.rerenderContextViewIfPresent(contextKey)
|
||||
}
|
||||
|
||||
func (gui *Gui) rerenderContextViewIfPresent(contextKey string) error {
|
||||
func (gui *Gui) rerenderContextViewIfPresent(contextKey ContextKey) error {
|
||||
if contextKey == "" {
|
||||
return nil
|
||||
}
|
||||
@ -184,7 +184,7 @@ func (gui *Gui) rerenderContextViewIfPresent(contextKey string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if view.Context == contextKey {
|
||||
if ContextKey(view.Context) == contextKey {
|
||||
if err := context.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func (gui *Gui) handleCommitFileSelect() error {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowFileDiffCmdStr(from, to, reverse, node.GetPath(), false),
|
||||
)
|
||||
task := gui.createRunPtyTask(cmd)
|
||||
task := NewRunPtyTask(cmd)
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
@ -287,7 +287,8 @@ func (gui *Gui) handleToggleCommitFileTreeView() error {
|
||||
}
|
||||
}
|
||||
|
||||
if gui.getCommitFilesView().Context == COMMIT_FILES_CONTEXT_KEY {
|
||||
// TODO: pretty sure this view only ever has this context. Is this if condition necessary?
|
||||
if gui.Views.CommitFiles.Context == COMMIT_FILES_CONTEXT_KEY {
|
||||
if err := gui.State.Contexts.CommitFiles.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ func (gui *Gui) runSyncOrAsyncCommand(sub *exec.Cmd, err error) (bool, error) {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCommitConfirm() error {
|
||||
commitMessageView := gui.getCommitMessageView()
|
||||
message := gui.trimmedContent(commitMessageView)
|
||||
message := gui.trimmedContent(gui.Views.CommitMessage)
|
||||
if message == "" {
|
||||
return gui.createErrorPanel(gui.Tr.CommitWithoutMessageErr)
|
||||
}
|
||||
@ -41,7 +40,7 @@ func (gui *Gui) handleCommitConfirm() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
gui.clearEditorView(commitMessageView)
|
||||
gui.clearEditorView(gui.Views.CommitMessage)
|
||||
_ = gui.returnFromContext()
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
||||
}
|
||||
@ -73,6 +72,6 @@ func (gui *Gui) RenderCommitLength() {
|
||||
if !gui.Config.GetUserConfig().Gui.CommitLength.Show {
|
||||
return
|
||||
}
|
||||
v := gui.getCommitMessageView()
|
||||
v.Subtitle = gui.getBufferLength(v)
|
||||
|
||||
gui.Views.CommitMessage.Subtitle = gui.getBufferLength(gui.Views.CommitMessage)
|
||||
}
|
||||
|
@ -35,12 +35,12 @@ func (gui *Gui) handleCommitSelect() error {
|
||||
var task updateTask
|
||||
commit := gui.getSelectedLocalCommit()
|
||||
if commit == nil {
|
||||
task = gui.createRenderStringTask(gui.Tr.NoCommitsThisBranch)
|
||||
task = NewRenderStringTask(gui.Tr.NoCommitsThisBranch)
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.Modes.Filtering.GetPath()),
|
||||
)
|
||||
task = gui.createRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -108,19 +108,17 @@ func (gui *Gui) wrappedPromptConfirmationFunction(handlersManageFocus bool, func
|
||||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) deleteConfirmationView() {
|
||||
func (gui *Gui) clearConfirmationViewKeyBindings() {
|
||||
keybindingConfig := gui.Config.GetUserConfig().Keybinding
|
||||
_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.Confirm), gocui.ModNone)
|
||||
_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.ConfirmAlt1), gocui.ModNone)
|
||||
_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.Return), gocui.ModNone)
|
||||
|
||||
_ = gui.g.DeleteView("confirmation")
|
||||
}
|
||||
|
||||
func (gui *Gui) closeConfirmationPrompt(handlersManageFocus bool) error {
|
||||
view := gui.getConfirmationView()
|
||||
if view == nil {
|
||||
return nil // if it's already been closed we can just return
|
||||
// we've already closed it so we can just return
|
||||
if !gui.Views.Confirmation.Visible {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !handlersManageFocus {
|
||||
@ -129,9 +127,9 @@ func (gui *Gui) closeConfirmationPrompt(handlersManageFocus bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
gui.deleteConfirmationView()
|
||||
|
||||
_, _ = gui.g.SetViewOnBottom("suggestions")
|
||||
gui.clearConfirmationViewKeyBindings()
|
||||
gui.Views.Confirmation.Visible = false
|
||||
gui.Views.Suggestions.Visible = false
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -200,7 +198,7 @@ func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, f
|
||||
suggestionsView.FgColor = theme.GocuiDefaultTextColor
|
||||
}
|
||||
gui.setSuggestions([]*types.Suggestion{})
|
||||
_, _ = gui.g.SetViewOnTop("suggestions")
|
||||
suggestionsView.Visible = true
|
||||
}
|
||||
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
@ -211,10 +209,9 @@ func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, f
|
||||
|
||||
func (gui *Gui) createPopupPanel(opts createPopupPanelOpts) error {
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
// delete the existing confirmation panel if it exists
|
||||
if view, _ := g.View("confirmation"); view != nil {
|
||||
gui.deleteConfirmationView()
|
||||
}
|
||||
// remove any previous keybindings
|
||||
gui.clearConfirmationViewKeyBindings()
|
||||
|
||||
confirmationView, err := gui.prepareConfirmationPanel(opts.title, opts.prompt, opts.hasLoader, opts.findSuggestionsFunc)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -251,7 +248,7 @@ func (gui *Gui) setKeyBindings(opts createPopupPanelOpts) error {
|
||||
gui.renderString("options", actions)
|
||||
var onConfirm func() error
|
||||
if opts.handleConfirmPrompt != nil {
|
||||
onConfirm = gui.wrappedPromptConfirmationFunction(opts.handlersManageFocus, opts.handleConfirmPrompt, func() string { return gui.getConfirmationView().Buffer() })
|
||||
onConfirm = gui.wrappedPromptConfirmationFunction(opts.handlersManageFocus, opts.handleConfirmPrompt, func() string { return gui.Views.Confirmation.Buffer() })
|
||||
} else {
|
||||
onConfirm = gui.wrappedConfirmationFunction(opts.handlersManageFocus, opts.handleConfirm)
|
||||
}
|
||||
|
@ -15,32 +15,34 @@ const (
|
||||
PERSISTENT_POPUP
|
||||
)
|
||||
|
||||
type ContextKey string
|
||||
|
||||
const (
|
||||
STATUS_CONTEXT_KEY = "status"
|
||||
FILES_CONTEXT_KEY = "files"
|
||||
LOCAL_BRANCHES_CONTEXT_KEY = "localBranches"
|
||||
REMOTES_CONTEXT_KEY = "remotes"
|
||||
REMOTE_BRANCHES_CONTEXT_KEY = "remoteBranches"
|
||||
TAGS_CONTEXT_KEY = "tags"
|
||||
BRANCH_COMMITS_CONTEXT_KEY = "commits"
|
||||
REFLOG_COMMITS_CONTEXT_KEY = "reflogCommits"
|
||||
SUB_COMMITS_CONTEXT_KEY = "subCommits"
|
||||
COMMIT_FILES_CONTEXT_KEY = "commitFiles"
|
||||
STASH_CONTEXT_KEY = "stash"
|
||||
MAIN_NORMAL_CONTEXT_KEY = "normal"
|
||||
MAIN_MERGING_CONTEXT_KEY = "merging"
|
||||
MAIN_PATCH_BUILDING_CONTEXT_KEY = "patchBuilding"
|
||||
MAIN_STAGING_CONTEXT_KEY = "staging"
|
||||
MENU_CONTEXT_KEY = "menu"
|
||||
CREDENTIALS_CONTEXT_KEY = "credentials"
|
||||
CONFIRMATION_CONTEXT_KEY = "confirmation"
|
||||
SEARCH_CONTEXT_KEY = "search"
|
||||
COMMIT_MESSAGE_CONTEXT_KEY = "commitMessage"
|
||||
SUBMODULES_CONTEXT_KEY = "submodules"
|
||||
SUGGESTIONS_CONTEXT_KEY = "suggestions"
|
||||
STATUS_CONTEXT_KEY ContextKey = "status"
|
||||
FILES_CONTEXT_KEY = "files"
|
||||
LOCAL_BRANCHES_CONTEXT_KEY = "localBranches"
|
||||
REMOTES_CONTEXT_KEY = "remotes"
|
||||
REMOTE_BRANCHES_CONTEXT_KEY = "remoteBranches"
|
||||
TAGS_CONTEXT_KEY = "tags"
|
||||
BRANCH_COMMITS_CONTEXT_KEY = "commits"
|
||||
REFLOG_COMMITS_CONTEXT_KEY = "reflogCommits"
|
||||
SUB_COMMITS_CONTEXT_KEY = "subCommits"
|
||||
COMMIT_FILES_CONTEXT_KEY = "commitFiles"
|
||||
STASH_CONTEXT_KEY = "stash"
|
||||
MAIN_NORMAL_CONTEXT_KEY = "normal"
|
||||
MAIN_MERGING_CONTEXT_KEY = "merging"
|
||||
MAIN_PATCH_BUILDING_CONTEXT_KEY = "patchBuilding"
|
||||
MAIN_STAGING_CONTEXT_KEY = "staging"
|
||||
MENU_CONTEXT_KEY = "menu"
|
||||
CREDENTIALS_CONTEXT_KEY = "credentials"
|
||||
CONFIRMATION_CONTEXT_KEY = "confirmation"
|
||||
SEARCH_CONTEXT_KEY = "search"
|
||||
COMMIT_MESSAGE_CONTEXT_KEY = "commitMessage"
|
||||
SUBMODULES_CONTEXT_KEY = "submodules"
|
||||
SUGGESTIONS_CONTEXT_KEY = "suggestions"
|
||||
)
|
||||
|
||||
var allContextKeys = []string{
|
||||
var allContextKeys = []ContextKey{
|
||||
STATUS_CONTEXT_KEY,
|
||||
FILES_CONTEXT_KEY,
|
||||
LOCAL_BRANCHES_CONTEXT_KEY,
|
||||
@ -124,7 +126,7 @@ type Context interface {
|
||||
GetViewName() string
|
||||
GetWindowName() string
|
||||
SetWindowName(string)
|
||||
GetKey() string
|
||||
GetKey() ContextKey
|
||||
SetParentContext(Context)
|
||||
|
||||
// we return a bool here to tell us whether or not the returned value just wraps a nil
|
||||
@ -138,7 +140,7 @@ type BasicContext struct {
|
||||
OnRender func() error
|
||||
OnGetOptionsMap func() map[string]string
|
||||
Kind ContextKind
|
||||
Key string
|
||||
Key ContextKey
|
||||
ViewName string
|
||||
}
|
||||
|
||||
@ -192,7 +194,7 @@ func (c BasicContext) GetKind() ContextKind {
|
||||
return c.Kind
|
||||
}
|
||||
|
||||
func (c BasicContext) GetKey() string {
|
||||
func (c BasicContext) GetKey() ContextKey {
|
||||
return c.Key
|
||||
}
|
||||
|
||||
@ -353,7 +355,7 @@ func (tree ContextTree) initialViewTabContextMap() map[string][]tabContext {
|
||||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) currentContextKeyIgnoringPopups() string {
|
||||
func (gui *Gui) currentContextKeyIgnoringPopups() ContextKey {
|
||||
gui.State.ContextManager.Lock()
|
||||
defer gui.State.ContextManager.Unlock()
|
||||
|
||||
@ -461,7 +463,10 @@ func (gui *Gui) returnFromContext() error {
|
||||
func (gui *Gui) deactivateContext(c Context) error {
|
||||
// if we are the kind of context that is sent to back upon deactivation, we should do that
|
||||
if c.GetKind() == TEMPORARY_POPUP || c.GetKind() == PERSISTENT_POPUP || c.GetKey() == COMMIT_FILES_CONTEXT_KEY {
|
||||
_, _ = gui.g.SetViewOnBottom(c.GetViewName())
|
||||
view, err := gui.g.View(c.GetViewName())
|
||||
if err == nil {
|
||||
view.Visible = false
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.HandleFocusLost(); err != nil {
|
||||
@ -480,7 +485,7 @@ func (gui *Gui) postRefreshUpdate(c Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if v.Context != c.GetKey() {
|
||||
if ContextKey(v.Context) != c.GetKey() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -504,7 +509,7 @@ func (gui *Gui) activateContext(c Context) error {
|
||||
if err != nil {
|
||||
return gui.returnFromContext()
|
||||
}
|
||||
originalViewContextKey := v.Context
|
||||
originalViewContextKey := ContextKey(v.Context)
|
||||
|
||||
// ensure that any other window for which this view was active is now set to the default for that window.
|
||||
gui.setViewAsActiveForWindow(viewName)
|
||||
@ -522,10 +527,7 @@ func (gui *Gui) activateContext(c Context) error {
|
||||
return gui.returnFromContext()
|
||||
}
|
||||
|
||||
if _, err := gui.g.SetViewOnTop(viewName); err != nil {
|
||||
// if view no longer exists, pop again
|
||||
return gui.returnFromContext()
|
||||
}
|
||||
v.Visible = true
|
||||
|
||||
// if the new context's view was previously displaying another context, render the new context
|
||||
if originalViewContextKey != c.GetKey() {
|
||||
@ -534,7 +536,7 @@ func (gui *Gui) activateContext(c Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
v.Context = c.GetKey()
|
||||
v.Context = string(c.GetKey())
|
||||
|
||||
gui.g.Cursor = v.Editable
|
||||
|
||||
@ -559,7 +561,7 @@ func (gui *Gui) activateContext(c Context) error {
|
||||
func (gui *Gui) renderContextStack() string {
|
||||
result := ""
|
||||
for _, context := range gui.State.ContextManager.ContextStack {
|
||||
result += context.GetKey() + "\n"
|
||||
result += string(context.GetKey()) + "\n"
|
||||
}
|
||||
return result
|
||||
}
|
||||
@ -575,7 +577,18 @@ func (gui *Gui) currentContext() Context {
|
||||
return gui.State.ContextManager.ContextStack[len(gui.State.ContextManager.ContextStack)-1]
|
||||
}
|
||||
|
||||
func (gui *Gui) currentSideContext() *ListContext {
|
||||
// the status panel is not yet a list context (and may never be), so this method is not
|
||||
// quite the same as currentSideContext()
|
||||
func (gui *Gui) currentSideListContext() *ListContext {
|
||||
context := gui.currentSideContext()
|
||||
listContext, ok := context.(*ListContext)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return listContext
|
||||
}
|
||||
|
||||
func (gui *Gui) currentSideContext() Context {
|
||||
gui.State.ContextManager.Lock()
|
||||
defer gui.State.ContextManager.Unlock()
|
||||
|
||||
@ -583,7 +596,7 @@ func (gui *Gui) currentSideContext() *ListContext {
|
||||
|
||||
// on startup the stack can be empty so we'll return an empty string in that case
|
||||
if len(stack) == 0 {
|
||||
return nil
|
||||
return gui.defaultSideContext()
|
||||
}
|
||||
|
||||
// find the first context in the stack with the type of SIDE_CONTEXT
|
||||
@ -591,20 +604,19 @@ func (gui *Gui) currentSideContext() *ListContext {
|
||||
context := stack[len(stack)-1-i]
|
||||
|
||||
if context.GetKind() == SIDE_CONTEXT {
|
||||
// not all side contexts are list contexts (e.g. the status panel)
|
||||
listContext, ok := context.(*ListContext)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return listContext
|
||||
return context
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return gui.defaultSideContext()
|
||||
}
|
||||
|
||||
func (gui *Gui) defaultSideContext() Context {
|
||||
return gui.State.Contexts.Files
|
||||
if gui.State.Modes.Filtering.Active() {
|
||||
return gui.State.Contexts.BranchCommits
|
||||
} else {
|
||||
return gui.State.Contexts.Files
|
||||
}
|
||||
}
|
||||
|
||||
// remove the need to do this: always use a mapping
|
||||
@ -618,7 +630,7 @@ func (gui *Gui) setInitialViewContexts() {
|
||||
continue
|
||||
}
|
||||
|
||||
view.Context = context.GetKey()
|
||||
view.Context = string(context.GetKey())
|
||||
}
|
||||
}
|
||||
|
||||
@ -678,15 +690,15 @@ func (gui *Gui) onViewFocusLost(v *gocui.View, newView *gocui.View) error {
|
||||
// which currently just means a context that affects both the main and secondary views
|
||||
// other views can have their context changed directly but this function helps
|
||||
// keep the main and secondary views in sync
|
||||
func (gui *Gui) changeMainViewsContext(contextKey string) {
|
||||
func (gui *Gui) changeMainViewsContext(contextKey ContextKey) {
|
||||
if gui.State.MainContext == contextKey {
|
||||
return
|
||||
}
|
||||
|
||||
switch contextKey {
|
||||
case MAIN_NORMAL_CONTEXT_KEY, MAIN_PATCH_BUILDING_CONTEXT_KEY, MAIN_STAGING_CONTEXT_KEY, MAIN_MERGING_CONTEXT_KEY:
|
||||
gui.getMainView().Context = contextKey
|
||||
gui.getSecondaryView().Context = contextKey
|
||||
gui.Views.Main.Context = string(contextKey)
|
||||
gui.Views.Secondary.Context = string(contextKey)
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown context for main: %s", contextKey))
|
||||
}
|
||||
@ -737,7 +749,7 @@ type tabContext struct {
|
||||
contexts []Context
|
||||
}
|
||||
|
||||
func (gui *Gui) mustContextForContextKey(contextKey string) Context {
|
||||
func (gui *Gui) mustContextForContextKey(contextKey ContextKey) Context {
|
||||
context, ok := gui.contextForContextKey(contextKey)
|
||||
|
||||
if !ok {
|
||||
@ -747,7 +759,7 @@ func (gui *Gui) mustContextForContextKey(contextKey string) Context {
|
||||
return context
|
||||
}
|
||||
|
||||
func (gui *Gui) contextForContextKey(contextKey string) (Context, bool) {
|
||||
func (gui *Gui) contextForContextKey(contextKey ContextKey) (Context, bool) {
|
||||
for _, context := range gui.allContexts() {
|
||||
if context.GetKey() == contextKey {
|
||||
return context, true
|
||||
@ -763,7 +775,7 @@ func (gui *Gui) rerenderView(viewName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
contextKey := v.Context
|
||||
contextKey := ContextKey(v.Context)
|
||||
context := gui.mustContextForContextKey(contextKey)
|
||||
|
||||
return context.HandleRender()
|
||||
@ -782,7 +794,7 @@ func (gui *Gui) rerenderView(viewName string) error {
|
||||
// }
|
||||
|
||||
func (gui *Gui) getSideContextSelectedItemId() string {
|
||||
currentSideContext := gui.currentSideContext()
|
||||
currentSideContext := gui.currentSideListContext()
|
||||
if currentSideContext == nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func (gui *Gui) promptUserForCredential(passOrUname string) string {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSubmitCredential() error {
|
||||
credentialsView := gui.getCredentialsView()
|
||||
credentialsView := gui.Views.Credentials
|
||||
message := gui.trimmedContent(credentialsView)
|
||||
gui.credentials <- message
|
||||
gui.clearEditorView(credentialsView)
|
||||
|
@ -176,9 +176,14 @@ func (gui *Gui) GetCustomCommandKeybindings() []*Binding {
|
||||
case "":
|
||||
log.Fatalf("Error parsing custom command keybindings: context not provided (use context: 'global' for the global context). Key: %s, Command: %s", customCommand.Key, customCommand.Command)
|
||||
default:
|
||||
context, ok := gui.contextForContextKey(customCommand.Context)
|
||||
context, ok := gui.contextForContextKey(ContextKey(customCommand.Context))
|
||||
// stupid golang making me build an array of strings for this.
|
||||
allContextKeyStrings := make([]string, len(allContextKeys))
|
||||
for i := range allContextKeys {
|
||||
allContextKeyStrings[i] = string(allContextKeys[i])
|
||||
}
|
||||
if !ok {
|
||||
log.Fatalf("Error when setting custom command keybindings: unknown context: %s. Key: %s, Command: %s.\nPermitted contexts: %s", customCommand.Context, customCommand.Key, customCommand.Command, strings.Join(allContextKeys, ", "))
|
||||
log.Fatalf("Error when setting custom command keybindings: unknown context: %s. Key: %s, Command: %s.\nPermitted contexts: %s", customCommand.Context, customCommand.Key, customCommand.Command, strings.Join(allContextKeyStrings, ", "))
|
||||
}
|
||||
// here we assume that a given context will always belong to the same view.
|
||||
// Currently this is a safe bet but it's by no means guaranteed in the long term
|
||||
|
@ -14,7 +14,7 @@ func (gui *Gui) renderDiff() error {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
fmt.Sprintf("git diff --submodule --no-ext-diff --color %s", gui.diffStr()),
|
||||
)
|
||||
task := gui.createRunPtyTask(cmd)
|
||||
task := NewRunPtyTask(cmd)
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
@ -49,7 +49,7 @@ func (gui *Gui) currentDiffTerminals() []string {
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
context := gui.currentSideContext()
|
||||
context := gui.currentSideListContext()
|
||||
if context == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func (gui *Gui) getSelectedPath() string {
|
||||
}
|
||||
|
||||
func (gui *Gui) selectFile(alreadySelected bool) error {
|
||||
gui.getFilesView().FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
|
||||
gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
|
||||
|
||||
node := gui.getSelectedFileNode()
|
||||
|
||||
@ -50,17 +50,17 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "",
|
||||
task: gui.createRenderStringTask(gui.Tr.NoChangedFiles),
|
||||
task: NewRenderStringTask(gui.Tr.NoChangedFiles),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if !alreadySelected {
|
||||
// TODO: pull into update task interface
|
||||
if err := gui.resetOrigin(gui.getMainView()); err != nil {
|
||||
if err := gui.resetOrigin(gui.Views.Main); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gui.resetOrigin(gui.getSecondaryView()); err != nil {
|
||||
if err := gui.resetOrigin(gui.Views.Secondary); err != nil {
|
||||
return err
|
||||
}
|
||||
gui.takeOverMergeConflictScrolling()
|
||||
@ -75,7 +75,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
|
||||
|
||||
refreshOpts := refreshMainOpts{main: &viewUpdateOpts{
|
||||
title: gui.Tr.UnstagedChanges,
|
||||
task: gui.createRunPtyTask(cmd),
|
||||
task: NewRunPtyTask(cmd),
|
||||
}}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
@ -85,7 +85,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
|
||||
|
||||
refreshOpts.secondary = &viewUpdateOpts{
|
||||
title: gui.Tr.StagedChanges,
|
||||
task: gui.createRunPtyTask(cmd),
|
||||
task: NewRunPtyTask(cmd),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -105,11 +105,6 @@ func (gui *Gui) refreshFilesAndSubmodules() error {
|
||||
|
||||
selectedPath := gui.getSelectedPath()
|
||||
|
||||
filesView := gui.getFilesView()
|
||||
if filesView == nil {
|
||||
// if the filesView hasn't been instantiated yet we just return
|
||||
return nil
|
||||
}
|
||||
if err := gui.refreshStateSubmoduleConfigs(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -122,14 +117,14 @@ func (gui *Gui) refreshFilesAndSubmodules() error {
|
||||
gui.Log.Error(err)
|
||||
}
|
||||
|
||||
if gui.getFilesView().Context == FILES_CONTEXT_KEY {
|
||||
if gui.Views.Files.Context == FILES_CONTEXT_KEY {
|
||||
// doing this a little custom (as opposed to using gui.postRefreshUpdate) because we handle selecting the file explicitly below
|
||||
if err := gui.State.Contexts.Files.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (g.CurrentView() == gui.getMainView() && g.CurrentView().Context == MAIN_MERGING_CONTEXT_KEY) {
|
||||
if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (g.CurrentView() == gui.Views.Main && g.CurrentView().Context == MAIN_MERGING_CONTEXT_KEY) {
|
||||
newSelectedPath := gui.getSelectedPath()
|
||||
alreadySelected := selectedPath != "" && newSelectedPath == selectedPath
|
||||
if err := gui.selectFile(alreadySelected); err != nil {
|
||||
@ -350,7 +345,7 @@ func (gui *Gui) handleWIPCommitPress() error {
|
||||
}
|
||||
|
||||
_ = gui.renderStringSync("commitMessage", skipHookPreifx)
|
||||
if err := gui.getCommitMessageView().SetCursor(len(skipHookPreifx), 0); err != nil {
|
||||
if err := gui.Views.CommitMessage.SetCursor(len(skipHookPreifx), 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -389,7 +384,6 @@ func (gui *Gui) handleCommitPress() error {
|
||||
return gui.promptToStageAllAndRetry(gui.handleCommitPress)
|
||||
}
|
||||
|
||||
commitMessageView := gui.getCommitMessageView()
|
||||
commitPrefixConfig := gui.commitPrefixConfigForRepo()
|
||||
if commitPrefixConfig != nil {
|
||||
prefixPattern := commitPrefixConfig.Pattern
|
||||
@ -400,7 +394,7 @@ func (gui *Gui) handleCommitPress() error {
|
||||
}
|
||||
prefix := rgx.ReplaceAllString(gui.getCheckedOutBranch().Name, prefixReplace)
|
||||
gui.renderString("commitMessage", prefix)
|
||||
if err := commitMessageView.SetCursor(len(prefix), 0); err != nil {
|
||||
if err := gui.Views.CommitMessage.SetCursor(len(prefix), 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -862,7 +856,7 @@ func (gui *Gui) handleToggleFileTreeView() error {
|
||||
}
|
||||
}
|
||||
|
||||
if gui.getFilesView().Context == FILES_CONTEXT_KEY {
|
||||
if gui.Views.Files.Context == FILES_CONTEXT_KEY {
|
||||
if err := gui.State.Contexts.Files.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
@ -59,30 +60,22 @@ func (gui *Gui) prevScreenMode() error {
|
||||
return gui.rerenderViewsWithScreenModeDependentContent()
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollUpView(viewName string) error {
|
||||
mainView, err := gui.g.View(viewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ox, oy := mainView.Origin()
|
||||
func (gui *Gui) scrollUpView(view *gocui.View) error {
|
||||
ox, oy := view.Origin()
|
||||
newOy := int(math.Max(0, float64(oy-gui.Config.GetUserConfig().Gui.ScrollHeight)))
|
||||
return mainView.SetOrigin(ox, newOy)
|
||||
return view.SetOrigin(ox, newOy)
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollDownView(viewName string) error {
|
||||
mainView, err := gui.g.View(viewName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
ox, oy := mainView.Origin()
|
||||
func (gui *Gui) scrollDownView(view *gocui.View) error {
|
||||
ox, oy := view.Origin()
|
||||
y := oy
|
||||
canScrollPastBottom := gui.Config.GetUserConfig().Gui.ScrollPastBottom
|
||||
if !canScrollPastBottom {
|
||||
_, sy := mainView.Size()
|
||||
_, sy := view.Size()
|
||||
y += sy
|
||||
}
|
||||
scrollHeight := gui.Config.GetUserConfig().Gui.ScrollHeight
|
||||
scrollableLines := mainView.ViewLinesHeight() - y
|
||||
scrollableLines := view.ViewLinesHeight() - y
|
||||
if scrollableLines > 0 {
|
||||
// margin is about how many lines must still appear if you scroll
|
||||
// all the way down. In practice every file ends in a newline so it will really
|
||||
@ -95,12 +88,12 @@ func (gui *Gui) scrollDownView(viewName string) error {
|
||||
scrollHeight = scrollableLines - margin
|
||||
}
|
||||
if oy+scrollHeight >= 0 {
|
||||
if err := mainView.SetOrigin(ox, oy+scrollHeight); err != nil {
|
||||
if err := view.SetOrigin(ox, oy+scrollHeight); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if manager, ok := gui.viewBufferManagerMap[viewName]; ok {
|
||||
if manager, ok := gui.viewBufferManagerMap[view.Name()]; ok {
|
||||
manager.ReadLines(scrollHeight)
|
||||
}
|
||||
return nil
|
||||
@ -111,7 +104,7 @@ func (gui *Gui) scrollUpMain() error {
|
||||
gui.State.Panels.Merging.UserScrolling = true
|
||||
}
|
||||
|
||||
return gui.scrollUpView("main")
|
||||
return gui.scrollUpView(gui.Views.Main)
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollDownMain() error {
|
||||
@ -119,33 +112,31 @@ func (gui *Gui) scrollDownMain() error {
|
||||
gui.State.Panels.Merging.UserScrolling = true
|
||||
}
|
||||
|
||||
return gui.scrollDownView("main")
|
||||
return gui.scrollDownView(gui.Views.Main)
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollUpSecondary() error {
|
||||
return gui.scrollUpView("secondary")
|
||||
return gui.scrollUpView(gui.Views.Secondary)
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollDownSecondary() error {
|
||||
return gui.scrollDownView("secondary")
|
||||
return gui.scrollDownView(gui.Views.Secondary)
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollUpConfirmationPanel() error {
|
||||
view := gui.getConfirmationView()
|
||||
if view != nil || view.Editable {
|
||||
if gui.Views.Confirmation.Editable {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.scrollUpView("confirmation")
|
||||
return gui.scrollUpView(gui.Views.Confirmation)
|
||||
}
|
||||
|
||||
func (gui *Gui) scrollDownConfirmationPanel() error {
|
||||
view := gui.getConfirmationView()
|
||||
if view != nil || view.Editable {
|
||||
if gui.Views.Confirmation.Editable {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.scrollDownView("confirmation")
|
||||
return gui.scrollDownView(gui.Views.Confirmation)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleRefresh() error {
|
||||
@ -157,16 +148,14 @@ func (gui *Gui) handleMouseDownMain() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
view := gui.getMainView()
|
||||
|
||||
switch gui.g.CurrentView().Name() {
|
||||
case "files":
|
||||
// set filename, set primary/secondary selected, set line number, then switch context
|
||||
// I'll need to know it was changed though.
|
||||
// Could I pass something along to the context change?
|
||||
return gui.enterFile(false, view.SelectedLineIdx())
|
||||
return gui.enterFile(false, gui.Views.Main.SelectedLineIdx())
|
||||
case "commitFiles":
|
||||
return gui.enterCommitFile(view.SelectedLineIdx())
|
||||
return gui.enterCommitFile(gui.Views.Main.SelectedLineIdx())
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -177,11 +166,9 @@ func (gui *Gui) handleMouseDownSecondary() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
view := gui.getSecondaryView()
|
||||
|
||||
switch gui.g.CurrentView().Name() {
|
||||
case "files":
|
||||
return gui.enterFile(true, view.SelectedLineIdx())
|
||||
return gui.enterFile(true, gui.Views.Secondary.SelectedLineIdx())
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -192,7 +179,7 @@ func (gui *Gui) handleInfoClick() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
view := gui.getInformationView()
|
||||
view := gui.Views.Information
|
||||
|
||||
cx, _ := view.Cursor()
|
||||
width, _ := view.Size()
|
||||
|
@ -106,6 +106,8 @@ type Gui struct {
|
||||
|
||||
// this tells us whether our views have been initially set up
|
||||
ViewsSetup bool
|
||||
|
||||
Views Views
|
||||
}
|
||||
|
||||
type RecordedEvent struct {
|
||||
@ -232,6 +234,28 @@ type panelStates struct {
|
||||
Suggestions *suggestionsPanelState
|
||||
}
|
||||
|
||||
type Views struct {
|
||||
Status *gocui.View
|
||||
Files *gocui.View
|
||||
Branches *gocui.View
|
||||
Commits *gocui.View
|
||||
Stash *gocui.View
|
||||
Main *gocui.View
|
||||
Secondary *gocui.View
|
||||
Options *gocui.View
|
||||
Confirmation *gocui.View
|
||||
Menu *gocui.View
|
||||
Credentials *gocui.View
|
||||
CommitMessage *gocui.View
|
||||
CommitFiles *gocui.View
|
||||
Information *gocui.View
|
||||
AppStatus *gocui.View
|
||||
Search *gocui.View
|
||||
SearchPrefix *gocui.View
|
||||
Limit *gocui.View
|
||||
Suggestions *gocui.View
|
||||
}
|
||||
|
||||
type searchingState struct {
|
||||
view *gocui.View
|
||||
isSearching bool
|
||||
@ -260,7 +284,7 @@ type CherryPicking struct {
|
||||
CherryPickedCommits []*models.Commit
|
||||
|
||||
// we only allow cherry picking from one context at a time, so you can't copy a commit from the local commits context and then also copy a commit in the reflog context
|
||||
ContextKey string
|
||||
ContextKey ContextKey
|
||||
}
|
||||
|
||||
func (m *CherryPicking) Active() bool {
|
||||
@ -306,8 +330,8 @@ type guiState struct {
|
||||
MenuItems []*menuItem
|
||||
Updating bool
|
||||
Panels *panelStates
|
||||
MainContext string // used to keep the main and secondary views' contexts in sync
|
||||
SplitMainPanel bool
|
||||
MainContext ContextKey // used to keep the main and secondary views' contexts in sync
|
||||
RetainOriginalDir bool
|
||||
IsRefreshingFiles bool
|
||||
Searching searchingState
|
||||
|
@ -625,21 +625,21 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
||||
ViewName: "branches",
|
||||
Contexts: []string{TAGS_CONTEXT_KEY},
|
||||
Key: gui.getKey(config.Universal.Select),
|
||||
Handler: gui.handleCheckoutTag,
|
||||
Handler: gui.withSelectedTag(gui.handleCheckoutTag),
|
||||
Description: gui.Tr.LcCheckout,
|
||||
},
|
||||
{
|
||||
ViewName: "branches",
|
||||
Contexts: []string{TAGS_CONTEXT_KEY},
|
||||
Key: gui.getKey(config.Universal.Remove),
|
||||
Handler: gui.handleDeleteTag,
|
||||
Handler: gui.withSelectedTag(gui.handleDeleteTag),
|
||||
Description: gui.Tr.LcDeleteTag,
|
||||
},
|
||||
{
|
||||
ViewName: "branches",
|
||||
Contexts: []string{TAGS_CONTEXT_KEY},
|
||||
Key: gui.getKey(config.Branches.PushTag),
|
||||
Handler: gui.handlePushTag,
|
||||
Handler: gui.withSelectedTag(gui.handlePushTag),
|
||||
Description: gui.Tr.LcPushTag,
|
||||
},
|
||||
{
|
||||
@ -653,7 +653,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
||||
ViewName: "branches",
|
||||
Contexts: []string{TAGS_CONTEXT_KEY},
|
||||
Key: gui.getKey(config.Commits.ViewResetOptions),
|
||||
Handler: gui.handleCreateResetToTagMenu,
|
||||
Handler: gui.withSelectedTag(gui.handleCreateResetToTagMenu),
|
||||
Description: gui.Tr.LcViewResetOptions,
|
||||
OpensMenu: true,
|
||||
},
|
||||
|
@ -31,29 +31,22 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
|
||||
minimumHeight := 9
|
||||
minimumWidth := 10
|
||||
if height < minimumHeight || width < minimumWidth {
|
||||
v, err := g.SetView("limit", 0, 0, width-1, height-1, 0)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
v.Title = gui.Tr.NotEnoughSpace
|
||||
v.Wrap = true
|
||||
_, _ = g.SetViewOnTop("limit")
|
||||
var err error
|
||||
gui.Views.Limit, err = g.SetView("limit", 0, 0, width-1, height-1, 0)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
gui.Views.Limit.Title = gui.Tr.NotEnoughSpace
|
||||
gui.Views.Limit.Wrap = true
|
||||
}
|
||||
gui.Views.Limit.Visible = height < minimumHeight || width < minimumWidth
|
||||
|
||||
informationStr := gui.informationStr()
|
||||
appStatus := gui.statusManager.getStatusString()
|
||||
|
||||
viewDimensions := gui.getWindowDimensions(informationStr, appStatus)
|
||||
|
||||
_, _ = g.SetViewOnBottom("limit")
|
||||
_ = g.DeleteView("limit")
|
||||
|
||||
textColor := theme.GocuiDefaultTextColor
|
||||
|
||||
// reading more lines into main view buffers upon resize
|
||||
prevMainView, err := gui.g.View("main")
|
||||
if err == nil {
|
||||
@ -79,17 +72,17 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
// to render content as soon as it appears, because lazyloaded content (via a pty task)
|
||||
// cares about the size of the view.
|
||||
view, err := g.SetView(viewName, 0, 0, width, height, 0)
|
||||
if err != nil {
|
||||
return view, err
|
||||
if view != nil {
|
||||
view.Visible = false
|
||||
}
|
||||
return g.SetViewOnBottom(viewName)
|
||||
return view, err
|
||||
}
|
||||
|
||||
frameOffset := 1
|
||||
if frame {
|
||||
frameOffset = 0
|
||||
}
|
||||
return g.SetView(
|
||||
view, err := g.SetView(
|
||||
viewName,
|
||||
dimensionsObj.X0-frameOffset,
|
||||
dimensionsObj.Y0-frameOffset,
|
||||
@ -97,172 +90,150 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
dimensionsObj.Y1+frameOffset,
|
||||
0,
|
||||
)
|
||||
|
||||
if view != nil {
|
||||
view.Visible = true
|
||||
}
|
||||
|
||||
return view, err
|
||||
}
|
||||
|
||||
v, err := setViewFromDimensions("main", "main", true)
|
||||
gui.Views.Main, err = setViewFromDimensions("main", "main", true)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
v.Title = gui.Tr.DiffTitle
|
||||
v.Wrap = true
|
||||
v.FgColor = textColor
|
||||
v.IgnoreCarriageReturns = true
|
||||
gui.Views.Main.Title = gui.Tr.DiffTitle
|
||||
gui.Views.Main.Wrap = true
|
||||
gui.Views.Main.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Main.IgnoreCarriageReturns = true
|
||||
}
|
||||
|
||||
secondaryView, err := setViewFromDimensions("secondary", "secondary", true)
|
||||
gui.Views.Secondary, err = setViewFromDimensions("secondary", "secondary", true)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
secondaryView.Title = gui.Tr.DiffTitle
|
||||
secondaryView.Wrap = true
|
||||
secondaryView.FgColor = textColor
|
||||
secondaryView.IgnoreCarriageReturns = true
|
||||
gui.Views.Secondary.Title = gui.Tr.DiffTitle
|
||||
gui.Views.Secondary.Wrap = true
|
||||
gui.Views.Secondary.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Secondary.IgnoreCarriageReturns = true
|
||||
}
|
||||
|
||||
hiddenViewOffset := 9999
|
||||
|
||||
if v, err := setViewFromDimensions("status", "status", true); err != nil {
|
||||
if gui.Views.Status, err = setViewFromDimensions("status", "status", true); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
v.Title = gui.Tr.StatusTitle
|
||||
v.FgColor = textColor
|
||||
gui.Views.Status.Title = gui.Tr.StatusTitle
|
||||
gui.Views.Status.FgColor = theme.GocuiDefaultTextColor
|
||||
}
|
||||
|
||||
filesView, err := setViewFromDimensions("files", "files", true)
|
||||
gui.Views.Files, err = setViewFromDimensions("files", "files", true)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
filesView.Highlight = true
|
||||
filesView.Title = gui.Tr.FilesTitle
|
||||
filesView.FgColor = textColor
|
||||
filesView.ContainsList = true
|
||||
gui.Views.Files.Highlight = true
|
||||
gui.Views.Files.Title = gui.Tr.FilesTitle
|
||||
gui.Views.Files.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Files.ContainsList = true
|
||||
}
|
||||
|
||||
branchesView, err := setViewFromDimensions("branches", "branches", true)
|
||||
gui.Views.Branches, err = setViewFromDimensions("branches", "branches", true)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
branchesView.Title = gui.Tr.BranchesTitle
|
||||
branchesView.FgColor = textColor
|
||||
branchesView.ContainsList = true
|
||||
gui.Views.Branches.Title = gui.Tr.BranchesTitle
|
||||
gui.Views.Branches.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Branches.ContainsList = true
|
||||
}
|
||||
|
||||
commitFilesView, err := setViewFromDimensions("commitFiles", gui.State.Contexts.CommitFiles.GetWindowName(), true)
|
||||
gui.Views.CommitFiles, err = setViewFromDimensions("commitFiles", gui.State.Contexts.CommitFiles.GetWindowName(), true)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
commitFilesView.Title = gui.Tr.CommitFiles
|
||||
commitFilesView.FgColor = textColor
|
||||
commitFilesView.ContainsList = true
|
||||
_, _ = gui.g.SetViewOnBottom("commitFiles")
|
||||
gui.Views.CommitFiles.Title = gui.Tr.CommitFiles
|
||||
gui.Views.CommitFiles.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.CommitFiles.ContainsList = true
|
||||
}
|
||||
// if the commit files view is the view to be displayed for its window, we'll display it
|
||||
gui.Views.CommitFiles.Visible = gui.getViewNameForWindow(gui.State.Contexts.CommitFiles.GetWindowName()) == "commitFiles"
|
||||
|
||||
commitsView, err := setViewFromDimensions("commits", "commits", true)
|
||||
gui.Views.Commits, err = setViewFromDimensions("commits", "commits", true)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
commitsView.Title = gui.Tr.CommitsTitle
|
||||
commitsView.FgColor = textColor
|
||||
commitsView.ContainsList = true
|
||||
gui.Views.Commits.Title = gui.Tr.CommitsTitle
|
||||
gui.Views.Commits.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Commits.ContainsList = true
|
||||
}
|
||||
|
||||
stashView, err := setViewFromDimensions("stash", "stash", true)
|
||||
gui.Views.Stash, err = setViewFromDimensions("stash", "stash", true)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
stashView.Title = gui.Tr.StashTitle
|
||||
stashView.FgColor = textColor
|
||||
stashView.ContainsList = true
|
||||
gui.Views.Stash.Title = gui.Tr.StashTitle
|
||||
gui.Views.Stash.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Stash.ContainsList = true
|
||||
}
|
||||
|
||||
if gui.getCommitMessageView() == nil {
|
||||
// doesn't matter where this view starts because it will be hidden
|
||||
if commitMessageView, err := g.SetView("commitMessage", hiddenViewOffset, hiddenViewOffset, hiddenViewOffset+10, hiddenViewOffset+10, 0); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
_, _ = g.SetViewOnBottom("commitMessage")
|
||||
commitMessageView.Title = gui.Tr.CommitMessage
|
||||
commitMessageView.FgColor = textColor
|
||||
commitMessageView.Editable = true
|
||||
commitMessageView.Editor = gocui.EditorFunc(gui.commitMessageEditor)
|
||||
}
|
||||
}
|
||||
|
||||
if check, _ := g.View("credentials"); check == nil {
|
||||
// doesn't matter where this view starts because it will be hidden
|
||||
if credentialsView, err := g.SetView("credentials", hiddenViewOffset, hiddenViewOffset, hiddenViewOffset+10, hiddenViewOffset+10, 0); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
_, _ = g.SetViewOnBottom("credentials")
|
||||
credentialsView.Title = gui.Tr.CredentialsUsername
|
||||
credentialsView.FgColor = textColor
|
||||
credentialsView.Editable = true
|
||||
}
|
||||
}
|
||||
|
||||
if v, err := setViewFromDimensions("options", "options", false); err != nil {
|
||||
if gui.Views.Options, err = setViewFromDimensions("options", "options", false); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
v.Frame = false
|
||||
v.FgColor = theme.OptionsColor
|
||||
gui.Views.Options.Frame = false
|
||||
gui.Views.Options.FgColor = theme.OptionsColor
|
||||
}
|
||||
|
||||
// this view takes up one character. Its only purpose is to show the slash when searching
|
||||
if searchPrefixView, err := setViewFromDimensions("searchPrefix", "searchPrefix", false); err != nil {
|
||||
if gui.Views.SearchPrefix, err = setViewFromDimensions("searchPrefix", "searchPrefix", false); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
|
||||
searchPrefixView.BgColor = gocui.ColorDefault
|
||||
searchPrefixView.FgColor = gocui.ColorGreen
|
||||
searchPrefixView.Frame = false
|
||||
gui.setViewContent(searchPrefixView, SEARCH_PREFIX)
|
||||
gui.Views.SearchPrefix.BgColor = gocui.ColorDefault
|
||||
gui.Views.SearchPrefix.FgColor = gocui.ColorGreen
|
||||
gui.Views.SearchPrefix.Frame = false
|
||||
gui.setViewContent(gui.Views.SearchPrefix, SEARCH_PREFIX)
|
||||
}
|
||||
|
||||
if searchView, err := setViewFromDimensions("search", "search", false); err != nil {
|
||||
if gui.Views.Search, err = setViewFromDimensions("search", "search", false); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
|
||||
searchView.BgColor = gocui.ColorDefault
|
||||
searchView.FgColor = gocui.ColorGreen
|
||||
searchView.Frame = false
|
||||
searchView.Editable = true
|
||||
gui.Views.Search.BgColor = gocui.ColorDefault
|
||||
gui.Views.Search.FgColor = gocui.ColorGreen
|
||||
gui.Views.Search.Frame = false
|
||||
gui.Views.Search.Editable = true
|
||||
}
|
||||
|
||||
if appStatusView, err := setViewFromDimensions("appStatus", "appStatus", false); err != nil {
|
||||
if gui.Views.AppStatus, err = setViewFromDimensions("appStatus", "appStatus", false); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
appStatusView.BgColor = gocui.ColorDefault
|
||||
appStatusView.FgColor = gocui.ColorCyan
|
||||
appStatusView.Frame = false
|
||||
_, _ = g.SetViewOnBottom("appStatus")
|
||||
gui.Views.AppStatus.BgColor = gocui.ColorDefault
|
||||
gui.Views.AppStatus.FgColor = gocui.ColorCyan
|
||||
gui.Views.AppStatus.Frame = false
|
||||
gui.Views.AppStatus.Visible = false
|
||||
}
|
||||
|
||||
informationView, err := setViewFromDimensions("information", "information", false)
|
||||
gui.Views.Information, err = setViewFromDimensions("information", "information", false)
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
informationView.BgColor = gocui.ColorDefault
|
||||
informationView.FgColor = gocui.ColorGreen
|
||||
informationView.Frame = false
|
||||
gui.Views.Information.BgColor = gocui.ColorDefault
|
||||
gui.Views.Information.FgColor = gocui.ColorGreen
|
||||
gui.Views.Information.Frame = false
|
||||
gui.renderString("information", INFO_SECTION_PADDING+informationStr)
|
||||
}
|
||||
if gui.State.OldInformation != informationStr {
|
||||
gui.setViewContent(informationView, informationStr)
|
||||
gui.setViewContent(gui.Views.Information, informationStr)
|
||||
gui.State.OldInformation = informationStr
|
||||
}
|
||||
|
||||
@ -289,7 +260,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
// ignore contexts whose view is owned by another context right now
|
||||
if view.Context != listContext.GetKey() {
|
||||
if ContextKey(view.Context) != listContext.GetKey() {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -302,9 +273,9 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
view.SetOnSelectItem(gui.onSelectItemWrapper(listContext.onSearchSelect))
|
||||
}
|
||||
|
||||
gui.getMainView().SetOnSelectItem(gui.onSelectItemWrapper(gui.handlelineByLineNavigateTo))
|
||||
gui.Views.Main.SetOnSelectItem(gui.onSelectItemWrapper(gui.handlelineByLineNavigateTo))
|
||||
|
||||
mainViewWidth, mainViewHeight := gui.getMainView().Size()
|
||||
mainViewWidth, mainViewHeight := gui.Views.Main.Size()
|
||||
if mainViewWidth != gui.State.PrevMainWidth || mainViewHeight != gui.State.PrevMainHeight {
|
||||
gui.State.PrevMainWidth = mainViewWidth
|
||||
gui.State.PrevMainHeight = mainViewHeight
|
||||
@ -320,28 +291,24 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
return gui.resizeCurrentPopupPanel()
|
||||
}
|
||||
|
||||
func (gui *Gui) setHiddenView(viewName string) (*gocui.View, error) {
|
||||
// arbitrarily giving the view enough size so that we don't get an error, but
|
||||
// it's expected that the view will be given the correct size before being shown
|
||||
return gui.g.SetView(viewName, 0, 0, 10, 10, 0)
|
||||
}
|
||||
|
||||
func (gui *Gui) onInitialViewsCreationForRepo() error {
|
||||
gui.setInitialViewContexts()
|
||||
|
||||
// hide any popup views. This only applies when we've just switched repos
|
||||
for _, viewName := range gui.popupViewNames() {
|
||||
_, _ = gui.g.SetViewOnBottom(viewName)
|
||||
}
|
||||
|
||||
// the status panel is not actually a list context at the moment, so it is excluded
|
||||
// here. Arguably that's quite convenient because it means we're back to starting
|
||||
// in the files panel when landing in a new repo, but when returning from a submodule
|
||||
// we'll be back in the submodules context. This still seems awkward though, and it's
|
||||
// definitely going to break when (if) we make the status context a list context
|
||||
initialContext := gui.currentSideContext()
|
||||
if initialContext == nil {
|
||||
if gui.State.Modes.Filtering.Active() {
|
||||
initialContext = gui.State.Contexts.BranchCommits
|
||||
} else {
|
||||
initialContext = gui.State.Contexts.Files
|
||||
view, err := gui.g.View(viewName)
|
||||
if err == nil {
|
||||
view.Visible = false
|
||||
}
|
||||
}
|
||||
|
||||
initialContext := gui.currentSideContext()
|
||||
if err := gui.pushContext(initialContext); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -350,6 +317,49 @@ func (gui *Gui) onInitialViewsCreationForRepo() error {
|
||||
}
|
||||
|
||||
func (gui *Gui) onInitialViewsCreation() error {
|
||||
// creating some views which are hidden at the start but we need to exist so that we can set an initial ordering
|
||||
if err := gui.createHiddenViews(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// now we order the views (in order of bottom first)
|
||||
layerOneViews := []*gocui.View{
|
||||
// first layer. Ordering within this layer does not matter because there are
|
||||
// no overlapping views
|
||||
gui.Views.Status,
|
||||
gui.Views.Files,
|
||||
gui.Views.Branches,
|
||||
gui.Views.Commits,
|
||||
gui.Views.Stash,
|
||||
gui.Views.CommitFiles,
|
||||
gui.Views.Main,
|
||||
gui.Views.Secondary,
|
||||
|
||||
// bottom line
|
||||
gui.Views.Options,
|
||||
gui.Views.AppStatus,
|
||||
gui.Views.Information,
|
||||
gui.Views.Search,
|
||||
gui.Views.SearchPrefix,
|
||||
|
||||
// popups. Ordering within this layer does not matter because there should
|
||||
// only be one popup shown at a time
|
||||
gui.Views.CommitMessage,
|
||||
gui.Views.Credentials,
|
||||
gui.Views.Menu,
|
||||
gui.Views.Confirmation,
|
||||
gui.Views.Suggestions,
|
||||
|
||||
// this guy will cover everything else when it appears
|
||||
gui.Views.Limit,
|
||||
}
|
||||
|
||||
for _, view := range layerOneViews {
|
||||
if _, err := gui.g.SetViewOnTop(view.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
gui.g.Mutexes.ViewsMutex.Lock()
|
||||
// add tabs to views
|
||||
for _, view := range gui.g.Views() {
|
||||
@ -378,3 +388,58 @@ func (gui *Gui) onInitialViewsCreation() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) createHiddenViews() error {
|
||||
// doesn't matter where this view starts because it will be hidden
|
||||
var err error
|
||||
if gui.Views.CommitMessage, err = gui.setHiddenView("commitMessage"); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
gui.Views.CommitMessage.Visible = false
|
||||
gui.Views.CommitMessage.Title = gui.Tr.CommitMessage
|
||||
gui.Views.CommitMessage.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.CommitMessage.Editable = true
|
||||
gui.Views.CommitMessage.Editor = gocui.EditorFunc(gui.commitMessageEditor)
|
||||
}
|
||||
|
||||
// doesn't matter where this view starts because it will be hidden
|
||||
if gui.Views.Credentials, err = gui.setHiddenView("credentials"); err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
gui.Views.Credentials.Visible = false
|
||||
gui.Views.Credentials.Title = gui.Tr.CredentialsUsername
|
||||
gui.Views.Credentials.FgColor = theme.GocuiDefaultTextColor
|
||||
gui.Views.Credentials.Editable = true
|
||||
}
|
||||
|
||||
// not worrying about setting attributes because that will be done when the view is actually shown
|
||||
gui.Views.Confirmation, err = gui.setHiddenView("confirmation")
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
gui.Views.Confirmation.Visible = false
|
||||
}
|
||||
|
||||
// not worrying about setting attributes because that will be done when the view is actually shown
|
||||
gui.Views.Suggestions, err = gui.setHiddenView("suggestions")
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
gui.Views.Suggestions.Visible = false
|
||||
}
|
||||
|
||||
// not worrying about setting attributes because that will be done when the view is actually shown
|
||||
gui.Views.Menu, err = gui.setHiddenView("menu")
|
||||
if err != nil {
|
||||
if err.Error() != UNKNOWN_VIEW_ERROR_MSG {
|
||||
return err
|
||||
}
|
||||
gui.Views.Menu.Visible = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -82,9 +82,8 @@ func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, second
|
||||
return false, err
|
||||
}
|
||||
|
||||
secondaryView := gui.getSecondaryView()
|
||||
secondaryView.Highlight = true
|
||||
secondaryView.Wrap = false
|
||||
gui.Views.Secondary.Highlight = true
|
||||
gui.Views.Secondary.Wrap = false
|
||||
|
||||
secondaryPatchParser, err := patch.NewPatchParser(gui.Log, secondaryDiff)
|
||||
if err != nil {
|
||||
@ -92,7 +91,7 @@ func (gui *Gui) refreshLineByLinePanel(diff string, secondaryDiff string, second
|
||||
}
|
||||
|
||||
gui.g.Update(func(*gocui.Gui) error {
|
||||
gui.setViewContent(gui.getSecondaryView(), secondaryPatchParser.Render(-1, -1, nil))
|
||||
gui.setViewContent(gui.Views.Secondary, secondaryPatchParser.Render(-1, -1, nil))
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -184,7 +183,7 @@ func (gui *Gui) handleLBLMouseDown() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
newSelectedLineIdx := gui.getMainView().SelectedLineIdx()
|
||||
newSelectedLineIdx := gui.Views.Main.SelectedLineIdx()
|
||||
state.FirstLineIdx = newSelectedLineIdx
|
||||
state.LastLineIdx = newSelectedLineIdx
|
||||
|
||||
@ -200,7 +199,7 @@ func (gui *Gui) handleMouseDrag() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.LBLSelectLine(gui.getMainView().SelectedLineIdx(), state)
|
||||
return gui.LBLSelectLine(gui.Views.Main.SelectedLineIdx(), state)
|
||||
})
|
||||
}
|
||||
|
||||
@ -248,12 +247,11 @@ func (gui *Gui) refreshMainViewForLineByLine(state *lBlPanelState) error {
|
||||
}
|
||||
colorDiff := state.PatchParser.Render(state.FirstLineIdx, state.LastLineIdx, includedLineIndices)
|
||||
|
||||
mainView := gui.getMainView()
|
||||
mainView.Highlight = true
|
||||
mainView.Wrap = false
|
||||
gui.Views.Main.Highlight = true
|
||||
gui.Views.Main.Wrap = false
|
||||
|
||||
gui.g.Update(func(*gocui.Gui) error {
|
||||
gui.setViewContent(gui.getMainView(), colorDiff)
|
||||
gui.setViewContent(gui.Views.Main, colorDiff)
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -263,7 +261,7 @@ func (gui *Gui) refreshMainViewForLineByLine(state *lBlPanelState) error {
|
||||
// focusSelection works out the best focus for the staging panel given the
|
||||
// selected line and size of the hunk
|
||||
func (gui *Gui) focusSelection(includeCurrentHunk bool, state *lBlPanelState) error {
|
||||
stagingView := gui.getMainView()
|
||||
stagingView := gui.Views.Main
|
||||
|
||||
_, viewHeight := stagingView.Size()
|
||||
bufferHeight := viewHeight - 1
|
||||
@ -367,7 +365,7 @@ func (gui *Gui) handleOpenFileAtLine() error {
|
||||
|
||||
func (gui *Gui) handleLineByLineNextPage() error {
|
||||
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||
newSelectedLineIdx := state.SelectedLineIdx + gui.pageDelta(gui.getMainView())
|
||||
newSelectedLineIdx := state.SelectedLineIdx + gui.pageDelta(gui.Views.Main)
|
||||
|
||||
return gui.lineByLineNavigateTo(newSelectedLineIdx, state)
|
||||
})
|
||||
@ -375,7 +373,7 @@ func (gui *Gui) handleLineByLineNextPage() error {
|
||||
|
||||
func (gui *Gui) handleLineByLinePrevPage() error {
|
||||
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||
newSelectedLineIdx := state.SelectedLineIdx - gui.pageDelta(gui.getMainView())
|
||||
newSelectedLineIdx := state.SelectedLineIdx - gui.pageDelta(gui.Views.Main)
|
||||
|
||||
return gui.lineByLineNavigateTo(newSelectedLineIdx, state)
|
||||
})
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
type ListContext struct {
|
||||
ViewName string
|
||||
ContextKey string
|
||||
ContextKey ContextKey
|
||||
GetItemsLength func() int
|
||||
GetDisplayStrings func() [][]string
|
||||
OnFocus func() error
|
||||
@ -103,7 +103,7 @@ func (lc *ListContext) OnRender() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lc *ListContext) GetKey() string {
|
||||
func (lc *ListContext) GetKey() ContextKey {
|
||||
return lc.ContextKey
|
||||
}
|
||||
|
||||
@ -136,10 +136,10 @@ func (lc *ListContext) HandleFocus() error {
|
||||
view.FocusPoint(0, lc.GetPanelState().GetSelectedLineIdx())
|
||||
|
||||
if lc.ResetMainViewOriginOnFocus {
|
||||
if err := lc.Gui.resetOrigin(lc.Gui.getMainView()); err != nil {
|
||||
if err := lc.Gui.resetOrigin(lc.Gui.Views.Main); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := lc.Gui.resetOrigin(lc.Gui.getSecondaryView()); err != nil {
|
||||
if err := lc.Gui.resetOrigin(lc.Gui.Views.Secondary); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -257,7 +257,7 @@ func (gui *Gui) menuListContext() *ListContext {
|
||||
return &ListContext{
|
||||
ViewName: "menu",
|
||||
ContextKey: "menu",
|
||||
GetItemsLength: func() int { return gui.getMenuView().LinesHeight() },
|
||||
GetItemsLength: func() int { return gui.Views.Menu.LinesHeight() },
|
||||
GetPanelState: func() IListPanelState { return gui.State.Panels.Menu },
|
||||
OnFocus: gui.handleMenuSelect,
|
||||
OnClickSelectedItem: gui.onMenuPress,
|
||||
@ -556,16 +556,16 @@ func (gui *Gui) getListContextKeyBindings() []*Binding {
|
||||
listContext := listContext
|
||||
|
||||
bindings = append(bindings, []*Binding{
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gui.getKey(keybindingConfig.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gui.getKey(keybindingConfig.Universal.PrevItem), Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gui.getKey(keybindingConfig.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gui.getKey(keybindingConfig.Universal.NextItem), Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gui.getKey(keybindingConfig.Universal.PrevPage), Modifier: gocui.ModNone, Handler: listContext.handlePrevPage, Description: gui.Tr.LcPrevPage},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gui.getKey(keybindingConfig.Universal.NextPage), Modifier: gocui.ModNone, Handler: listContext.handleNextPage, Description: gui.Tr.LcNextPage},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gui.getKey(keybindingConfig.Universal.GotoTop), Modifier: gocui.ModNone, Handler: listContext.handleGotoTop, Description: gui.Tr.LcGotoTop},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{listContext.ContextKey}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
|
||||
{ViewName: listContext.ViewName, Contexts: []string{listContext.ContextKey}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: listContext.handleClick},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gui.getKey(keybindingConfig.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gui.getKey(keybindingConfig.Universal.PrevItem), Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gui.getKey(keybindingConfig.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gui.getKey(keybindingConfig.Universal.NextItem), Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gui.getKey(keybindingConfig.Universal.PrevPage), Modifier: gocui.ModNone, Handler: listContext.handlePrevPage, Description: gui.Tr.LcPrevPage},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gui.getKey(keybindingConfig.Universal.NextPage), Modifier: gocui.ModNone, Handler: listContext.handleNextPage, Description: gui.Tr.LcNextPage},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gui.getKey(keybindingConfig.Universal.GotoTop), Modifier: gocui.ModNone, Handler: listContext.handleGotoTop, Description: gui.Tr.LcGotoTop},
|
||||
{ViewName: listContext.ViewName, Tag: "navigation", Contexts: []string{string(listContext.ContextKey)}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
|
||||
{ViewName: listContext.ViewName, Contexts: []string{string(listContext.ContextKey)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: listContext.handleClick},
|
||||
}...)
|
||||
|
||||
// the commits panel needs to lazyload things so it has a couple of its own handlers
|
||||
@ -579,7 +579,7 @@ func (gui *Gui) getListContextKeyBindings() []*Binding {
|
||||
bindings = append(bindings, []*Binding{
|
||||
{
|
||||
ViewName: listContext.ViewName,
|
||||
Contexts: []string{listContext.ContextKey},
|
||||
Contexts: []string{string(listContext.ContextKey)},
|
||||
Key: gui.getKey(keybindingConfig.Universal.StartSearch),
|
||||
Handler: func() error { return openSearchHandler(listContext.ViewName) },
|
||||
Description: gui.Tr.LcStartSearch,
|
||||
@ -587,7 +587,7 @@ func (gui *Gui) getListContextKeyBindings() []*Binding {
|
||||
},
|
||||
{
|
||||
ViewName: listContext.ViewName,
|
||||
Contexts: []string{listContext.ContextKey},
|
||||
Contexts: []string{string(listContext.ContextKey)},
|
||||
Key: gui.getKey(keybindingConfig.Universal.GotoBottom),
|
||||
Handler: gotoBottomHandler,
|
||||
Description: gui.Tr.LcGotoBottom,
|
||||
|
@ -1,6 +1,10 @@
|
||||
package gui
|
||||
|
||||
import "os/exec"
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
)
|
||||
|
||||
type viewUpdateOpts struct {
|
||||
title string
|
||||
@ -42,7 +46,7 @@ func (t *renderStringTask) GetKind() TaskKind {
|
||||
return RENDER_STRING
|
||||
}
|
||||
|
||||
func (gui *Gui) createRenderStringTask(str string) *renderStringTask {
|
||||
func NewRenderStringTask(str string) *renderStringTask {
|
||||
return &renderStringTask{str: str}
|
||||
}
|
||||
|
||||
@ -54,7 +58,7 @@ func (t *renderStringWithoutScrollTask) GetKind() TaskKind {
|
||||
return RENDER_STRING_WITHOUT_SCROLL
|
||||
}
|
||||
|
||||
func (gui *Gui) createRenderStringWithoutScrollTask(str string) *renderStringWithoutScrollTask {
|
||||
func NewRenderStringWithoutScrollTask(str string) *renderStringWithoutScrollTask {
|
||||
return &renderStringWithoutScrollTask{str: str}
|
||||
}
|
||||
|
||||
@ -67,11 +71,11 @@ func (t *runCommandTask) GetKind() TaskKind {
|
||||
return RUN_COMMAND
|
||||
}
|
||||
|
||||
func (gui *Gui) createRunCommandTask(cmd *exec.Cmd) *runCommandTask {
|
||||
func NewRunCommandTask(cmd *exec.Cmd) *runCommandTask {
|
||||
return &runCommandTask{cmd: cmd}
|
||||
}
|
||||
|
||||
func (gui *Gui) createRunCommandTaskWithPrefix(cmd *exec.Cmd, prefix string) *runCommandTask {
|
||||
func NewRunCommandTaskWithPrefix(cmd *exec.Cmd, prefix string) *runCommandTask {
|
||||
return &runCommandTask{cmd: cmd, prefix: prefix}
|
||||
}
|
||||
|
||||
@ -84,7 +88,7 @@ func (t *runPtyTask) GetKind() TaskKind {
|
||||
return RUN_PTY
|
||||
}
|
||||
|
||||
func (gui *Gui) createRunPtyTask(cmd *exec.Cmd) *runPtyTask {
|
||||
func NewRunPtyTask(cmd *exec.Cmd) *runPtyTask {
|
||||
return &runPtyTask{cmd: cmd}
|
||||
}
|
||||
|
||||
@ -134,18 +138,12 @@ func (gui *Gui) runTaskForView(viewName string, task updateTask) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshMainView(opts *viewUpdateOpts, viewName string) error {
|
||||
view, err := gui.g.View(viewName)
|
||||
if err != nil {
|
||||
gui.Log.Error(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshMainView(opts *viewUpdateOpts, view *gocui.View) error {
|
||||
view.Title = opts.title
|
||||
view.Wrap = !opts.noWrap
|
||||
view.Highlight = opts.highlight
|
||||
|
||||
if err := gui.runTaskForView(viewName, opts.task); err != nil {
|
||||
if err := gui.runTaskForView(view.Name(), opts.task); err != nil {
|
||||
gui.Log.Error(err)
|
||||
return nil
|
||||
}
|
||||
@ -155,19 +153,19 @@ func (gui *Gui) refreshMainView(opts *viewUpdateOpts, viewName string) error {
|
||||
|
||||
func (gui *Gui) refreshMainViews(opts refreshMainOpts) error {
|
||||
if opts.main != nil {
|
||||
if err := gui.refreshMainView(opts.main, "main"); err != nil {
|
||||
if err := gui.refreshMainView(opts.main, gui.Views.Main); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if opts.secondary != nil {
|
||||
if err := gui.refreshMainView(opts.secondary, gui.Views.Secondary); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
gui.splitMainPanel(opts.secondary != nil)
|
||||
|
||||
if opts.secondary != nil {
|
||||
if err := gui.refreshMainView(opts.secondary, "secondary"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -176,7 +174,7 @@ func (gui *Gui) splitMainPanel(splitMainPanel bool) {
|
||||
|
||||
// no need to set view on bottom when splitMainPanel is false: it will have zero size anyway thanks to our view arrangement code.
|
||||
if splitMainPanel {
|
||||
_, _ = gui.g.SetViewOnTop("secondary")
|
||||
gui.Views.Secondary.Visible = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,6 @@ func (gui *Gui) getMenuOptions() map[string]string {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleMenuClose() error {
|
||||
_ = gui.g.DeleteView("menu")
|
||||
return gui.returnFromContext()
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ func (gui *Gui) refreshMergePanel() error {
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "",
|
||||
task: gui.createRenderStringTask(err.Error()),
|
||||
task: NewRenderStringTask(err.Error()),
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -203,7 +203,7 @@ func (gui *Gui) refreshMergePanel() error {
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: gui.Tr.MergeConflictsTitle,
|
||||
task: gui.createRenderStringWithoutScrollTask(content),
|
||||
task: NewRenderStringWithoutScrollTask(content),
|
||||
noWrap: true,
|
||||
},
|
||||
})
|
||||
@ -236,7 +236,8 @@ func (gui *Gui) scrollToConflict() error {
|
||||
if len(panelState.Conflicts) == 0 {
|
||||
return nil
|
||||
}
|
||||
mergingView := gui.getMainView()
|
||||
|
||||
mergingView := gui.Views.Main
|
||||
conflict := panelState.Conflicts[panelState.ConflictIndex]
|
||||
ox, _ := mergingView.Origin()
|
||||
_, height := mergingView.Size()
|
||||
@ -269,7 +270,7 @@ func (gui *Gui) handleEscapeMerge() error {
|
||||
}
|
||||
// it's possible this method won't be called from the merging view so we need to
|
||||
// ensure we only 'return' focus if we already have it
|
||||
if gui.g.CurrentView() == gui.getMainView() {
|
||||
if gui.g.CurrentView() == gui.Views.Main {
|
||||
return gui.pushContext(gui.State.Contexts.Files)
|
||||
}
|
||||
return nil
|
||||
|
@ -22,10 +22,8 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int, state *lBlPanelSt
|
||||
return gui.handleEscapePatchBuildingPanel()
|
||||
}
|
||||
|
||||
gui.splitMainPanel(true)
|
||||
|
||||
gui.getMainView().Title = "Patch"
|
||||
gui.getSecondaryView().Title = "Custom Patch"
|
||||
gui.Views.Main.Title = "Patch"
|
||||
gui.Views.Secondary.Title = "Custom Patch"
|
||||
|
||||
// get diff from commit file that's currently selected
|
||||
node := gui.getSelectedCommitFileNode()
|
||||
@ -125,7 +123,7 @@ func (gui *Gui) secondaryPatchPanelUpdateOpts() *viewUpdateOpts {
|
||||
title: "Custom Patch",
|
||||
noWrap: true,
|
||||
highlight: true,
|
||||
task: gui.createRenderStringWithoutScrollTask(patch),
|
||||
task: NewRenderStringWithoutScrollTask(patch),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,7 @@ func (gui *Gui) onResize() error {
|
||||
if gui.State.Ptmx == nil {
|
||||
return nil
|
||||
}
|
||||
mainView := gui.getMainView()
|
||||
width, height := mainView.Size()
|
||||
width, height := gui.Views.Main.Size()
|
||||
|
||||
if err := pty.Setsize(gui.State.Ptmx, &pty.Winsize{Cols: uint16(width), Rows: uint16(height)}); err != nil {
|
||||
return err
|
||||
@ -31,7 +30,7 @@ func (gui *Gui) onResize() error {
|
||||
// pseudo-terminal meaning we'll get the behaviour we want from the underlying
|
||||
// command.
|
||||
func (gui *Gui) newPtyTask(viewName string, cmd *exec.Cmd, prefix string) error {
|
||||
width, _ := gui.getMainView().Size()
|
||||
width, _ := gui.Views.Main.Size()
|
||||
pager := gui.GitCommand.GetPager(width)
|
||||
|
||||
if pager == "" {
|
||||
|
@ -40,7 +40,7 @@ func (gui *Gui) handleShowAllBranchLogs() error {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.Config.GetUserConfig().Git.AllBranchesLogCmd,
|
||||
)
|
||||
task := gui.createRunPtyTask(cmd)
|
||||
task := NewRunPtyTask(cmd)
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
|
@ -20,13 +20,13 @@ func (gui *Gui) handleReflogCommitSelect() error {
|
||||
commit := gui.getSelectedReflogCommit()
|
||||
var task updateTask
|
||||
if commit == nil {
|
||||
task = gui.createRenderStringTask("No reflog history")
|
||||
task = NewRenderStringTask("No reflog history")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.Modes.Filtering.GetPath()),
|
||||
)
|
||||
|
||||
task = gui.createRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -22,12 +22,12 @@ func (gui *Gui) handleRemoteBranchSelect() error {
|
||||
var task updateTask
|
||||
remoteBranch := gui.getSelectedRemoteBranch()
|
||||
if remoteBranch == nil {
|
||||
task = gui.createRenderStringTask("No branches for this remote")
|
||||
task = NewRenderStringTask("No branches for this remote")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.GetBranchGraphCmdStr(remoteBranch.FullName()),
|
||||
)
|
||||
task = gui.createRunCommandTask(cmd)
|
||||
task = NewRunCommandTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -24,9 +24,9 @@ func (gui *Gui) handleRemoteSelect() error {
|
||||
var task updateTask
|
||||
remote := gui.getSelectedRemote()
|
||||
if remote == nil {
|
||||
task = gui.createRenderStringTask("No remotes")
|
||||
task = NewRenderStringTask("No remotes")
|
||||
} else {
|
||||
task = gui.createRenderStringTask(fmt.Sprintf("%s\nUrls:\n%s", utils.ColoredString(remote.Name, color.FgGreen), strings.Join(remote.Urls, "\n")))
|
||||
task = NewRenderStringTask(fmt.Sprintf("%s\nUrls:\n%s", utils.ColoredString(remote.Name, color.FgGreen), strings.Join(remote.Urls, "\n")))
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
@ -57,12 +57,7 @@ func (gui *Gui) refreshRemotes() error {
|
||||
}
|
||||
}
|
||||
|
||||
branchesView := gui.getBranchesView()
|
||||
if branchesView != nil {
|
||||
return gui.postRefreshUpdate(gui.mustContextForContextKey(branchesView.Context))
|
||||
}
|
||||
|
||||
return nil
|
||||
return gui.postRefreshUpdate(gui.mustContextForContextKey(ContextKey(gui.Views.Branches.Context)))
|
||||
}
|
||||
|
||||
func (gui *Gui) handleRemoteEnter() error {
|
||||
|
@ -26,7 +26,7 @@ func (gui *Gui) handleOpenSearch(viewName string) error {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSearch() error {
|
||||
gui.State.Searching.searchString = gui.getSearchView().Buffer()
|
||||
gui.State.Searching.searchString = gui.Views.Search.Buffer()
|
||||
if err := gui.returnFromContext(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ func (gui *Gui) nextSideWindow() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := gui.resetOrigin(gui.getMainView()); err != nil {
|
||||
if err := gui.resetOrigin(gui.Views.Main); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ func (gui *Gui) previousSideWindow() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := gui.resetOrigin(gui.getMainView()); err != nil {
|
||||
if err := gui.resetOrigin(gui.Views.Main); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,11 @@ func (gui *Gui) refreshStagingPanel(forceSecondaryFocused bool, selectedLineIdx
|
||||
}
|
||||
|
||||
if secondaryFocused {
|
||||
gui.getMainView().Title = gui.Tr.StagedChanges
|
||||
gui.getSecondaryView().Title = gui.Tr.UnstagedChanges
|
||||
gui.Views.Main.Title = gui.Tr.StagedChanges
|
||||
gui.Views.Secondary.Title = gui.Tr.UnstagedChanges
|
||||
} else {
|
||||
gui.getMainView().Title = gui.Tr.UnstagedChanges
|
||||
gui.getSecondaryView().Title = gui.Tr.StagedChanges
|
||||
gui.Views.Main.Title = gui.Tr.UnstagedChanges
|
||||
gui.Views.Secondary.Title = gui.Tr.StagedChanges
|
||||
}
|
||||
|
||||
// note for custom diffs, we'll need to send a flag here saying not to use the custom diff
|
||||
@ -63,7 +63,7 @@ func (gui *Gui) handleTogglePanelClick() error {
|
||||
return gui.withLBLActiveCheck(func(state *lBlPanelState) error {
|
||||
state.SecondaryFocused = !state.SecondaryFocused
|
||||
|
||||
return gui.refreshStagingPanel(false, gui.getSecondaryView().SelectedLineIdx(), state)
|
||||
return gui.refreshStagingPanel(false, gui.Views.Secondary.SelectedLineIdx(), state)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,12 @@ func (gui *Gui) handleStashEntrySelect() error {
|
||||
var task updateTask
|
||||
stashEntry := gui.getSelectedStashEntry()
|
||||
if stashEntry == nil {
|
||||
task = gui.createRenderStringTask(gui.Tr.NoStashEntries)
|
||||
task = NewRenderStringTask(gui.Tr.NoStashEntries)
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowStashEntryCmdStr(stashEntry.Index),
|
||||
)
|
||||
task = gui.createRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
|
@ -43,7 +43,7 @@ func (gui *Gui) refreshStatus() {
|
||||
status += fmt.Sprintf("%s → %s ", repoName, name)
|
||||
|
||||
gui.g.Update(func(*gocui.Gui) error {
|
||||
gui.setViewContent(gui.getStatusView(), status)
|
||||
gui.setViewContent(gui.Views.Status, status)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@ -77,7 +77,7 @@ func (gui *Gui) handleStatusClick() error {
|
||||
return err
|
||||
}
|
||||
|
||||
cx, _ := gui.getStatusView().Cursor()
|
||||
cx, _ := gui.Views.Status.Cursor()
|
||||
upstreamStatus := fmt.Sprintf("↑%s↓%s", currentBranch.Pushables, currentBranch.Pullables)
|
||||
repoName := utils.GetCurrentRepoName()
|
||||
switch gui.GitCommand.WorkingTreeState() {
|
||||
@ -121,7 +121,7 @@ func (gui *Gui) handleStatusSelect() error {
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "",
|
||||
task: gui.createRenderStringTask(dashboardString),
|
||||
task: NewRenderStringTask(dashboardString),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -21,13 +21,13 @@ func (gui *Gui) handleSubCommitSelect() error {
|
||||
commit := gui.getSelectedSubCommit()
|
||||
var task updateTask
|
||||
if commit == nil {
|
||||
task = gui.createRenderStringTask("No commits")
|
||||
task = NewRenderStringTask("No commits")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.Modes.Filtering.GetPath()),
|
||||
)
|
||||
|
||||
task = gui.createRunPtyTask(cmd)
|
||||
task = NewRunPtyTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
@ -94,13 +94,13 @@ func (gui *Gui) switchToSubCommitsContext(refName string) error {
|
||||
gui.State.SubCommits = commits
|
||||
gui.State.Panels.SubCommits.refName = refName
|
||||
gui.State.Panels.SubCommits.SelectedLineIdx = 0
|
||||
gui.State.Contexts.SubCommits.SetParentContext(gui.currentSideContext())
|
||||
gui.State.Contexts.SubCommits.SetParentContext(gui.currentSideListContext())
|
||||
|
||||
return gui.pushContext(gui.State.Contexts.SubCommits)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSwitchToSubCommits() error {
|
||||
currentContext := gui.currentSideContext()
|
||||
currentContext := gui.currentSideListContext()
|
||||
if currentContext == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ func (gui *Gui) handleSubmoduleSelect() error {
|
||||
var task updateTask
|
||||
submodule := gui.getSelectedSubmodule()
|
||||
if submodule == nil {
|
||||
task = gui.createRenderStringTask("No submodules")
|
||||
task = NewRenderStringTask("No submodules")
|
||||
} else {
|
||||
prefix := fmt.Sprintf(
|
||||
"Name: %s\nPath: %s\nUrl: %s\n\n",
|
||||
@ -35,11 +35,11 @@ func (gui *Gui) handleSubmoduleSelect() error {
|
||||
|
||||
file := gui.fileForSubmodule(submodule)
|
||||
if file == nil {
|
||||
task = gui.createRenderStringTask(prefix)
|
||||
task = NewRenderStringTask(prefix)
|
||||
} else {
|
||||
cmdStr := gui.GitCommand.WorktreeFileDiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges)
|
||||
cmd := gui.OSCommand.ExecutableFromString(cmdStr)
|
||||
task = gui.createRunCommandTaskWithPrefix(cmd, prefix)
|
||||
task = NewRunCommandTaskWithPrefix(cmd, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,13 +24,8 @@ func (gui *Gui) getSelectedSuggestion() *types.Suggestion {
|
||||
}
|
||||
|
||||
func (gui *Gui) setSuggestions(suggestions []*types.Suggestion) {
|
||||
view := gui.getSuggestionsView()
|
||||
if view == nil {
|
||||
return
|
||||
}
|
||||
|
||||
gui.State.Suggestions = suggestions
|
||||
gui.State.Panels.Suggestions.SelectedLineIdx = 0
|
||||
_ = gui.resetOrigin(view)
|
||||
_ = gui.resetOrigin(gui.Views.Suggestions)
|
||||
_ = gui.State.Contexts.Suggestions.HandleRender()
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedTag() *models.Tag {
|
||||
selectedLine := gui.State.Panels.Tags.SelectedLineIdx
|
||||
if selectedLine == -1 || len(gui.State.Tags) == 0 {
|
||||
@ -16,100 +14,6 @@ func (gui *Gui) getSelectedTag() *models.Tag {
|
||||
return gui.State.Tags[selectedLine]
|
||||
}
|
||||
|
||||
func (gui *Gui) handleTagSelect() error {
|
||||
var task updateTask
|
||||
tag := gui.getSelectedTag()
|
||||
if tag == nil {
|
||||
task = gui.createRenderStringTask("No tags")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.GetBranchGraphCmdStr(tag.Name),
|
||||
)
|
||||
task = gui.createRunCommandTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "Tag",
|
||||
task: task,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshTags() error {
|
||||
tags, err := gui.GitCommand.GetTags()
|
||||
if err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
|
||||
gui.State.Tags = tags
|
||||
|
||||
return gui.postRefreshUpdate(gui.State.Contexts.Tags)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCheckoutTag() error {
|
||||
tag := gui.getSelectedTag()
|
||||
if tag == nil {
|
||||
return nil
|
||||
}
|
||||
if err := gui.handleCheckoutRef(tag.Name, handleCheckoutRefOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return gui.pushContext(gui.State.Contexts.Branches)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleDeleteTag() error {
|
||||
tag := gui.getSelectedTag()
|
||||
if tag == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
prompt := utils.ResolvePlaceholderString(
|
||||
gui.Tr.DeleteTagPrompt,
|
||||
map[string]string{
|
||||
"tagName": tag.Name,
|
||||
},
|
||||
)
|
||||
|
||||
return gui.ask(askOpts{
|
||||
title: gui.Tr.DeleteTagTitle,
|
||||
prompt: prompt,
|
||||
handleConfirm: func() error {
|
||||
if err := gui.GitCommand.DeleteTag(tag.Name); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) handlePushTag() error {
|
||||
tag := gui.getSelectedTag()
|
||||
if tag == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
title := utils.ResolvePlaceholderString(
|
||||
gui.Tr.PushTagTitle,
|
||||
map[string]string{
|
||||
"tagName": tag.Name,
|
||||
},
|
||||
)
|
||||
|
||||
return gui.prompt(promptOpts{
|
||||
title: title,
|
||||
initialContent: "origin",
|
||||
handleConfirm: func(response string) error {
|
||||
return gui.WithWaitingStatus(gui.Tr.PushingTagStatus, func() error {
|
||||
err := gui.GitCommand.PushTag(response, tag.Name, gui.promptUserForCredential)
|
||||
gui.handleCredentialsPopup(err)
|
||||
|
||||
return nil
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCreateTag() error {
|
||||
return gui.prompt(promptOpts{
|
||||
title: gui.Tr.CreateTagTitle,
|
||||
@ -136,11 +40,98 @@ func (gui *Gui) handleCreateTag() error {
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCreateResetToTagMenu() error {
|
||||
// tag-specific handlers
|
||||
// view model would need to raise an event called 'tag selected', perhaps containing a tag. The listener would _be_ the main view, or the main context, and it would be able to render to itself.
|
||||
func (gui *Gui) handleTagSelect() error {
|
||||
var task updateTask
|
||||
tag := gui.getSelectedTag()
|
||||
if tag == nil {
|
||||
task = NewRenderStringTask("No tags")
|
||||
} else {
|
||||
cmd := gui.OSCommand.ExecutableFromString(
|
||||
gui.GitCommand.GetBranchGraphCmdStr(tag.Name),
|
||||
)
|
||||
task = NewRunCommandTask(cmd)
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "Tag",
|
||||
task: task,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// this is a controller: it can't access tags directly. Or can it? It should be able to get but not set. But that's exactly what I'm doing here, setting it. but through a mutator which encapsulates the event.
|
||||
func (gui *Gui) refreshTags() error {
|
||||
tags, err := gui.GitCommand.GetTags()
|
||||
if err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
|
||||
gui.State.Tags = tags
|
||||
|
||||
return gui.postRefreshUpdate(gui.State.Contexts.Tags)
|
||||
}
|
||||
|
||||
func (gui *Gui) withSelectedTag(f func(tag *models.Tag) error) func() error {
|
||||
tag := gui.getSelectedTag()
|
||||
if tag == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return func() error { return f(tag) }
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCheckoutTag(tag *models.Tag) error {
|
||||
if err := gui.handleCheckoutRef(tag.Name, handleCheckoutRefOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return gui.pushContext(gui.State.Contexts.Branches)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleDeleteTag(tag *models.Tag) error {
|
||||
prompt := utils.ResolvePlaceholderString(
|
||||
gui.Tr.DeleteTagPrompt,
|
||||
map[string]string{
|
||||
"tagName": tag.Name,
|
||||
},
|
||||
)
|
||||
|
||||
return gui.ask(askOpts{
|
||||
title: gui.Tr.DeleteTagTitle,
|
||||
prompt: prompt,
|
||||
handleConfirm: func() error {
|
||||
if err := gui.GitCommand.DeleteTag(tag.Name); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []RefreshableView{COMMITS, TAGS}})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) handlePushTag(tag *models.Tag) error {
|
||||
title := utils.ResolvePlaceholderString(
|
||||
gui.Tr.PushTagTitle,
|
||||
map[string]string{
|
||||
"tagName": tag.Name,
|
||||
},
|
||||
)
|
||||
|
||||
return gui.prompt(promptOpts{
|
||||
title: title,
|
||||
initialContent: "origin",
|
||||
handleConfirm: func(response string) error {
|
||||
return gui.WithWaitingStatus(gui.Tr.PushingTagStatus, func() error {
|
||||
err := gui.GitCommand.PushTag(response, tag.Name, gui.promptUserForCredential)
|
||||
gui.handleCredentialsPopup(err)
|
||||
|
||||
return nil
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCreateResetToTagMenu(tag *models.Tag) error {
|
||||
return gui.createResetMenu(tag.Name)
|
||||
}
|
||||
|
@ -241,88 +241,6 @@ func (gui *Gui) renderOptionsMap(optionsMap map[string]string) {
|
||||
gui.renderString("options", gui.optionsMapToString(optionsMap))
|
||||
}
|
||||
|
||||
func (gui *Gui) getFilesView() *gocui.View {
|
||||
v, _ := gui.g.View("files")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getCommitFilesView() *gocui.View {
|
||||
v, _ := gui.g.View("commitFiles")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getCommitsView() *gocui.View {
|
||||
v, _ := gui.g.View("commits")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getCredentialsView() *gocui.View {
|
||||
v, _ := gui.g.View("commits")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getCommitMessageView() *gocui.View {
|
||||
v, _ := gui.g.View("commitMessage")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getBranchesView() *gocui.View {
|
||||
v, _ := gui.g.View("branches")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getMainView() *gocui.View {
|
||||
v, _ := gui.g.View("main")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getSuggestionsView() *gocui.View {
|
||||
v, _ := gui.g.View("suggestions")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getSecondaryView() *gocui.View {
|
||||
v, _ := gui.g.View("secondary")
|
||||
return v
|
||||
}
|
||||
|
||||
// currently unused
|
||||
// func (gui *Gui) getStashView() *gocui.View {
|
||||
// v, _ := gui.g.View("stash")
|
||||
// return v
|
||||
// }
|
||||
|
||||
// currently unused
|
||||
// func (gui *Gui) getCommitFilesView() *gocui.View {
|
||||
// v, _ := gui.g.View("commitFiles")
|
||||
// return v
|
||||
// }
|
||||
|
||||
func (gui *Gui) getMenuView() *gocui.View {
|
||||
v, _ := gui.g.View("menu")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getSearchView() *gocui.View {
|
||||
v, _ := gui.g.View("search")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getStatusView() *gocui.View {
|
||||
v, _ := gui.g.View("status")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getConfirmationView() *gocui.View {
|
||||
v, _ := gui.g.View("confirmation")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) getInformationView() *gocui.View {
|
||||
v, _ := gui.g.View("information")
|
||||
return v
|
||||
}
|
||||
|
||||
func (gui *Gui) trimmedContent(v *gocui.View) string {
|
||||
return strings.TrimSpace(v.Buffer())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user