package keymap

import 

// action is represents the action of a widget, the number of times
// this widget needs to be run, and an optional operator argument.
// Most of the time we don't need this operator.
//
// Those actions are mostly used by widgets which make the shell enter
// the Vim operator pending mode, and thus require another key to be read.
type action struct {
	command inputrc.Bind
}

// Pending registers a command as waiting for another command to run first,
// such as yank/delete/change actions, which accept/require a movement command.
func ( *Engine) () {
	.SetLocal(ViOpp)
	.skip = true

	// Push the widget on the stack of widgets
	.pending = append(.pending, .active)
}

// CancelPending is used by commands that have been registering themselves
// as waiting for a pending operator, but have actually been called twice
// in a row (eg. dd/yy in Vim mode). This removes those commands from queue.
func ( *Engine) () {
	if len(.pending) == 0 {
		return
	}

	.pending = .pending[:len(.pending)-1]

	if len(.pending) == 0 && .Local() == ViOpp {
		.SetLocal("")
	}
}

// IsPending returns true when invoked from within the command
// that also happens to be the next in line of pending commands.
func ( *Engine) () bool {
	if len(.pending) == 0 {
		return false
	}

	return .active.Action == .pending[0].Action
}

// RunPending runs any command with pending execution.
func ( *Engine) () {
	if len(.pending) == 0 {
		return
	}

	if .skip {
		.skip = false
		return
	}

	defer .UpdateCursor()

	// Get the last registered action.
	 := .pending[len(.pending)-1]
	.pending = .pending[:len(.pending)-1]

	// The same command might be used twice in a row (dd/yy)
	if .Action == .active.Action {
		.isCaller = true
		defer func() { .isCaller = false }()
	}

	if .Action == "" {
		return
	}

	// Resolve and run the command
	 := .resolve()

	()

	// And adapt the local keymap.
	if len(.pending) == 0 && .Local() == ViOpp {
		.SetLocal("")
	}
}