tasks

package
v0.66.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const COMMAND_START_THRESHOLD = time.Millisecond * 10

we use this to check if the system is under stress right now. Hopefully this makes sense on other machines

View Source
const THROTTLE_TIME = time.Millisecond * 30

Variables

This section is empty.

Functions

This section is empty.

Types

type AsyncHandler added in v0.30.1

type AsyncHandler struct {
	// contains filtered or unexported fields
}

the purpose of an AsyncHandler is to ensure that if we have multiple long-running requests, we only handle the result of the latest one. For example, if I am searching for 'abc' and I have to type 'a' then 'b' then 'c' and each keypress dispatches a request to search for things with the string so-far, we'll be searching for 'a', 'ab', and 'abc', and it may be that 'abc' comes back first, then 'ab', then 'a' and we don't want to display the result for 'a' just because it came back last. AsyncHandler keeps track of the order in which things were dispatched so that we can ignore anything that comes back late.

func NewAsyncHandler added in v0.30.1

func NewAsyncHandler(onWorker func(func(gocui.Task) error)) *AsyncHandler

func (*AsyncHandler) Do added in v0.30.1

func (self *AsyncHandler) Do(f func() func())

type Cmd added in v0.63.0

type Cmd interface {
	Wait() error
	String() string
	// Terminate makes the process stop early, as gracefully as the platform
	// allows. It doesn't wait for the process to exit.
	Terminate() error
}

Cmd abstracts over a started external process. *exec.Cmd satisfies the bulk of it via ExecCmd, but pty implementations can supply their own types — on Windows, ConPTY has to spawn via CreateProcess directly and can't use *exec.Cmd (see golang/go#62708).

type ExecCmd added in v0.63.0

type ExecCmd struct {
	*exec.Cmd
}

ExecCmd adapts *exec.Cmd to Cmd.

func (ExecCmd) Terminate added in v0.64.0

func (c ExecCmd) Terminate() error

Terminate sends SIGTERM on Unix. On Windows it does nothing, so a stopped command keeps running until it next writes to its (by then closed) output pipe.

type LinesToRead added in v0.38.0

type LinesToRead struct {
	// The total number of lines the task should have read once this request is
	// satisfied. This is an absolute count from the start of the task, not a
	// delta: the task keeps track of how many lines it has already read and only
	// reads the shortfall, so a request for a total at or below what has already
	// been read reads nothing. -1 means read all the way to the end.
	Total int

	// Number of lines after which we have read enough to fill the view, and can
	// do an initial refresh. Only set for the initial read request; -1 for
	// subsequent requests.
	InitialRefreshAfter int

	// Function to call after reading the lines is done
	Then func()
}

type RenderRestore added in v0.66.0

type RenderRestore struct {
	// FirstPaintReady reports whether enough of the new content has been read for
	// the restore to show what it is looking for. It is consulted after each line
	// is read, on the task's own goroutine.
	FirstPaintReady func() bool

	// Apply runs once, on the UI thread, at the first paint. It finds its target in
	// the off-screen content, calls swapIn to promote that content to the display,
	// and places the view on the target — in that order, so that the search runs
	// while the previous content is still displayed, and the new content is never
	// drawn at the previous render's scroll position.
	//
	// It must call swapIn even when it finds nothing to place the view on, in which
	// case the view keeps the position the paint gave it: the offset it had, or the
	// top for content the view hasn't seen.
	Apply func(swapIn func())

	// Done is called once the restore has had its render — after Apply, or when it
	// is given up because the view is being shown something other than a re-render
	// of what it was remembered from. It is how a caller that has to wait for the
	// view to be back where it belongs knows that it either is, or never will be.
	// Optional, and called on the UI thread, as Apply is.
	Done func()
}

RenderRestore puts a view back where it was when it re-renders content the user is already looking at, laid out differently — a different context size, whitespace ignored, another diff renderer — instead of showing the new render from the top.

The task reads the new content into an off-screen buffer; the restore says when enough of it has arrived to show the remembered position (FirstPaintReady), and then finds that position and reveals it (Apply). It is a pair of callbacks rather than a scroll position because a different layout of the same content puts the remembered line somewhere else, and only the new content itself says where.

type TaskOpts added in v0.39.0

type TaskOpts struct {
	// Channel that tells the task to stop, because another task wants to run.
	Stop chan struct{}

	// Only for tasks which are long-running, where we read more lines sporadically.
	// We use this to keep track of when a user's action is complete (i.e. all views
	// have been refreshed to display the results of their action)
	InitialContentLoaded func()
	// contains filtered or unexported fields
}

type TaskReservation added in v0.66.0

type TaskReservation struct {
	// contains filtered or unexported fields
}

A TaskReservation holds a task's place in the order of the view's tasks, from when the task is asked for until it is created. See ReserveTask.

type ViewBufferManager

type ViewBufferManager struct {
	Log *logrus.Entry
	// contains filtered or unexported fields
}

func NewViewBufferManager

func NewViewBufferManager(
	log *logrus.Entry,
	writer io.Writer,
	beforeStart func(),
	refreshView func(),
	onEndOfInput func(),
	resetOrigin func(),
	beginRender func(),
	swapInRender func(),
	newGocuiTask func() gocui.Task,
	onUIThread func(f func()) error,
) *ViewBufferManager

func (*ViewBufferManager) Close

func (self *ViewBufferManager) Close()

Close closes the task manager, killing whatever task may currently be running

func (*ViewBufferManager) DropRestoreForNextTask added in v0.66.0

func (self *ViewBufferManager) DropRestoreForNextTask()

DropRestoreForNextTask gives up a restore that has no render to ride, because the view is being given something other than a re-render of the content it was remembered from — a message where a diff was. Without this the restore would sit there and claim some later render of that view, putting the user somewhere they haven't been for a while.

func (*ViewBufferManager) ForgetRenderedContent added in v0.66.0

func (self *ViewBufferManager) ForgetRenderedContent()

ForgetRenderedContent records that the view no longer shows the render whose key it is holding, because it has been emptied. The key says what the view is showing, and the next task is compared against it to tell whether that task renders something new. A view with nothing in it is showing nothing, so whatever comes next is new.

func (*ViewBufferManager) GetTaskKey added in v0.30.1

func (self *ViewBufferManager) GetTaskKey() string

func (*ViewBufferManager) HasRestoreForNextTask added in v0.66.0

func (self *ViewBufferManager) HasRestoreForNextTask() bool

HasRestoreForNextTask reports whether the next command task already has a position waiting to be put back, for a caller that would otherwise install one of its own over it.

func (*ViewBufferManager) IsLoading added in v0.65.0

func (self *ViewBufferManager) IsLoading() bool

IsLoading reports whether the task asked for last is a command task that is still reading content into the view, meaning the content is still growing.

func (*ViewBufferManager) IsSuperseded added in v0.66.0

func (self *ViewBufferManager) IsSuperseded(reservation TaskReservation) bool

IsSuperseded reports whether another task has been asked for since the reservation was made. The reserved task would then stop as soon as it was created, so there is no point in creating it.

func (*ViewBufferManager) NewCmdTask

func (self *ViewBufferManager) NewCmdTask(start func() (Cmd, io.Reader), prefix func() string, linesToRead LinesToRead, onDoneFn func()) func(TaskOpts) error

NewCmdTask returns a task that renders the output of the command that start starts. prefix, unless nil, produces the text shown above that output. It is called on the task's goroutine before the command starts, so a prefix that takes a while to produce holds up only this task.

func (*ViewBufferManager) NewReservedTask added in v0.66.0

func (self *ViewBufferManager) NewReservedTask(reservation TaskReservation, f func(TaskOpts) error, key string) error

NewReservedTask creates the task that the reservation was made for. It doesn't run if another task has been asked for since the reservation was made.

func (*ViewBufferManager) NewTask

func (self *ViewBufferManager) NewTask(f func(TaskOpts) error, key string) error

NewTask creates a task that takes its place in the order of the view's tasks right away.

func (*ViewBufferManager) ReadLines

func (self *ViewBufferManager) ReadLines(totalLines int)

ReadLines asks the task to ensure it has read at least totalLines lines in total. Because the count is absolute rather than a delta, repeated requests (e.g. as the user scrolls down, back up, and down again) don't re-read lines that have already been read: the task only ever reads the shortfall.

func (*ViewBufferManager) ReadLinesAndWait added in v0.66.0

func (self *ViewBufferManager) ReadLinesAndWait(totalLines int)

ReadLinesAndWait is ReadLines for lines lazygit is itself waiting on, rather than reading ahead of the user. It holds a gocui task until they have been read, so lazygit doesn't count as idle in the meantime (docs/dev/Busy.md).

func (*ViewBufferManager) ReadToEnd added in v0.50.0

func (self *ViewBufferManager) ReadToEnd(then func())

func (*ViewBufferManager) ReserveTask added in v0.66.0

func (self *ViewBufferManager) ReserveTask() TaskReservation

ReserveTask gives a task its place in the order of the view's tasks, for a task that is only created later, with NewReservedTask. The view shows the task that was asked for last. If another task is asked for after the reservation, that task replaces the reserved one, even when it is created first.

func (*ViewBufferManager) SetKeepScrollPositionForNextTask added in v0.66.0

func (self *ViewBufferManager) SetKeepScrollPositionForNextTask()

SetKeepScrollPositionForNextTask arranges for the next command task to leave the view's scroll position alone, rather than showing its content from the top the way a render of different content does. Call it right before triggering a re-render of the content the view is showing, when the command producing it is not the one that produced what is on screen — a different context size, another diff renderer.

It is the coarser sibling of SetRestoreForNextTask, for the same moment. The restore puts the view back on the line it remembers, which it can only do when the lines of the new rendering can be told apart. This one says merely "the content is a rearrangement of what is there, so the offset into it is nearer to where the user was than the top is". Both can be set at once, and then the restore has the first say.

func (*ViewBufferManager) SetRestoreForNextTask added in v0.66.0

func (self *ViewBufferManager) SetRestoreForNextTask(restore *RenderRestore)

SetRestoreForNextTask arranges for the next command task to put the view back where it is now once it has re-rendered. Call it right before triggering a re-render of the content the view is showing; see RenderRestore.

func (*ViewBufferManager) StartLoading added in v0.65.0

func (self *ViewBufferManager) StartLoading()

StartLoading marks the view as loading the output of the task asked for last, which must be a command task. Call it right when that task is asked for, before its goroutine runs and before the next layout pass, so that the layout doesn't clamp the scroll position to the not-yet-loaded content. The view stops loading when the task reaches the end of its input, or when another task is asked for.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL