mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-03-21 21:47:32 +02:00
Add WithInlineStatus helper function
Very similar to WithWaitingStatus, except that the status is shown in a view next to the affected item, rather than in the status bar. Not used by anything yet; again, committing separately to get smaller commits.
This commit is contained in:
parent
9d55d71fdd
commit
7075b66bc6
@ -112,6 +112,7 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||||||
Confirmation: helpers.NewConfirmationHelper(helperCommon),
|
Confirmation: helpers.NewConfirmationHelper(helperCommon),
|
||||||
Mode: modeHelper,
|
Mode: modeHelper,
|
||||||
AppStatus: appStatusHelper,
|
AppStatus: appStatusHelper,
|
||||||
|
InlineStatus: helpers.NewInlineStatusHelper(helperCommon),
|
||||||
WindowArrangement: helpers.NewWindowArrangementHelper(
|
WindowArrangement: helpers.NewWindowArrangementHelper(
|
||||||
gui.c,
|
gui.c,
|
||||||
windowHelper,
|
windowHelper,
|
||||||
|
@ -46,6 +46,7 @@ type Helpers struct {
|
|||||||
Confirmation *ConfirmationHelper
|
Confirmation *ConfirmationHelper
|
||||||
Mode *ModeHelper
|
Mode *ModeHelper
|
||||||
AppStatus *AppStatusHelper
|
AppStatus *AppStatusHelper
|
||||||
|
InlineStatus *InlineStatusHelper
|
||||||
WindowArrangement *WindowArrangementHelper
|
WindowArrangement *WindowArrangementHelper
|
||||||
Search *SearchHelper
|
Search *SearchHelper
|
||||||
Worktree *WorktreeHelper
|
Worktree *WorktreeHelper
|
||||||
@ -81,6 +82,7 @@ func NewStubHelpers() *Helpers {
|
|||||||
Confirmation: &ConfirmationHelper{},
|
Confirmation: &ConfirmationHelper{},
|
||||||
Mode: &ModeHelper{},
|
Mode: &ModeHelper{},
|
||||||
AppStatus: &AppStatusHelper{},
|
AppStatus: &AppStatusHelper{},
|
||||||
|
InlineStatus: &InlineStatusHelper{},
|
||||||
WindowArrangement: &WindowArrangementHelper{},
|
WindowArrangement: &WindowArrangementHelper{},
|
||||||
Search: &SearchHelper{},
|
Search: &SearchHelper{},
|
||||||
Worktree: &WorktreeHelper{},
|
Worktree: &WorktreeHelper{},
|
||||||
|
129
pkg/gui/controllers/helpers/inline_status_helper.go
Normal file
129
pkg/gui/controllers/helpers/inline_status_helper.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/gocui"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
|
"github.com/sasha-s/go-deadlock"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InlineStatusHelper struct {
|
||||||
|
c *HelperCommon
|
||||||
|
|
||||||
|
contextsWithInlineStatus map[types.ContextKey]*inlineStatusInfo
|
||||||
|
mutex *deadlock.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInlineStatusHelper(c *HelperCommon) *InlineStatusHelper {
|
||||||
|
return &InlineStatusHelper{
|
||||||
|
c: c,
|
||||||
|
contextsWithInlineStatus: make(map[types.ContextKey]*inlineStatusInfo),
|
||||||
|
mutex: &deadlock.Mutex{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type InlineStatusOpts struct {
|
||||||
|
Item types.HasUrn
|
||||||
|
Operation types.ItemOperation
|
||||||
|
ContextKey types.ContextKey
|
||||||
|
}
|
||||||
|
|
||||||
|
type inlineStatusInfo struct {
|
||||||
|
refCount int
|
||||||
|
stop chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A custom task for WithInlineStatus calls; it wraps the original one and
|
||||||
|
// hides the status whenever the task is paused, and shows it again when
|
||||||
|
// continued.
|
||||||
|
type inlineStatusHelperTask struct {
|
||||||
|
gocui.Task
|
||||||
|
|
||||||
|
inlineStatusHelper *InlineStatusHelper
|
||||||
|
opts InlineStatusOpts
|
||||||
|
}
|
||||||
|
|
||||||
|
// poor man's version of explicitly saying that struct X implements interface Y
|
||||||
|
var _ gocui.Task = inlineStatusHelperTask{}
|
||||||
|
|
||||||
|
func (self inlineStatusHelperTask) Pause() {
|
||||||
|
self.inlineStatusHelper.stop(self.opts)
|
||||||
|
self.Task.Pause()
|
||||||
|
|
||||||
|
self.inlineStatusHelper.renderContext(self.opts.ContextKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self inlineStatusHelperTask) Continue() {
|
||||||
|
self.Task.Continue()
|
||||||
|
self.inlineStatusHelper.start(self.opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *InlineStatusHelper) WithInlineStatus(opts InlineStatusOpts, f func(gocui.Task) error) {
|
||||||
|
self.c.OnWorker(func(task gocui.Task) {
|
||||||
|
self.start(opts)
|
||||||
|
|
||||||
|
err := f(inlineStatusHelperTask{task, self, opts})
|
||||||
|
if err != nil {
|
||||||
|
self.c.OnUIThread(func() error {
|
||||||
|
return self.c.Error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.stop(opts)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *InlineStatusHelper) start(opts InlineStatusOpts) {
|
||||||
|
self.c.State().SetItemOperation(opts.Item, opts.Operation)
|
||||||
|
|
||||||
|
self.mutex.Lock()
|
||||||
|
defer self.mutex.Unlock()
|
||||||
|
|
||||||
|
info := self.contextsWithInlineStatus[opts.ContextKey]
|
||||||
|
if info == nil {
|
||||||
|
info = &inlineStatusInfo{refCount: 0, stop: make(chan struct{})}
|
||||||
|
self.contextsWithInlineStatus[opts.ContextKey] = info
|
||||||
|
|
||||||
|
go utils.Safe(func() {
|
||||||
|
ticker := time.NewTicker(time.Millisecond * utils.LoaderAnimationInterval)
|
||||||
|
defer ticker.Stop()
|
||||||
|
outer:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
self.renderContext(opts.ContextKey)
|
||||||
|
case <-info.stop:
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
info.refCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *InlineStatusHelper) stop(opts InlineStatusOpts) {
|
||||||
|
self.mutex.Lock()
|
||||||
|
|
||||||
|
if info := self.contextsWithInlineStatus[opts.ContextKey]; info != nil {
|
||||||
|
info.refCount--
|
||||||
|
if info.refCount <= 0 {
|
||||||
|
info.stop <- struct{}{}
|
||||||
|
delete(self.contextsWithInlineStatus, opts.ContextKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mutex.Unlock()
|
||||||
|
|
||||||
|
self.c.State().ClearItemOperation(opts.Item)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *InlineStatusHelper) renderContext(contextKey types.ContextKey) {
|
||||||
|
self.c.OnUIThread(func() error {
|
||||||
|
_ = self.c.ContextForKey(contextKey).HandleRender()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -199,3 +200,8 @@ func (self *guiCommon) RunningIntegrationTest() bool {
|
|||||||
func (self *guiCommon) InDemo() bool {
|
func (self *guiCommon) InDemo() bool {
|
||||||
return self.gui.integrationTest != nil && self.gui.integrationTest.IsDemo()
|
return self.gui.integrationTest != nil && self.gui.integrationTest.IsDemo()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *guiCommon) WithInlineStatus(item types.HasUrn, operation types.ItemOperation, contextKey types.ContextKey, f func(gocui.Task) error) error {
|
||||||
|
self.gui.helpers.InlineStatus.WithInlineStatus(helpers.InlineStatusOpts{Item: item, Operation: operation, ContextKey: contextKey}, f)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -87,6 +87,12 @@ type IGuiCommon interface {
|
|||||||
// resized, if in accordion mode.
|
// resized, if in accordion mode.
|
||||||
AfterLayout(f func() error)
|
AfterLayout(f func() error)
|
||||||
|
|
||||||
|
// Wraps a function, attaching the given operation to the given item while
|
||||||
|
// the function is executing, and also causes the given context to be
|
||||||
|
// redrawn periodically. This allows the operation to be visualized with a
|
||||||
|
// spinning loader animation (e.g. when a branch is being pushed).
|
||||||
|
WithInlineStatus(item HasUrn, operation ItemOperation, contextKey ContextKey, f func(gocui.Task) error) error
|
||||||
|
|
||||||
// returns the gocui Gui struct. There is a good chance you don't actually want to use
|
// returns the gocui Gui struct. There is a good chance you don't actually want to use
|
||||||
// this struct and instead want to use another method above
|
// this struct and instead want to use another method above
|
||||||
GocuiGui() *gocui.Gui
|
GocuiGui() *gocui.Gui
|
||||||
|
Loading…
x
Reference in New Issue
Block a user