package readline

import (
	

	
	
	
	
)

func ( *Shell) () commands {
	return map[string]func(){
		"complete":               .completeWord,
		"possible-completions":   .possibleCompletions,
		"insert-completions":     .insertCompletions,
		"menu-complete":          .menuComplete,
		"menu-complete-backward": .menuCompleteBackward,
		"delete-char-or-list":    .deleteCharOrList,

		"menu-complete-next-tag":   .menuCompleteNextTag,
		"menu-complete-prev-tag":   .menuCompletePrevTag,
		"accept-and-menu-complete": .acceptAndMenuComplete,
		"vi-registers-complete":    .viRegistersComplete,
		"menu-incremental-search":  .menuIncrementalSearch,
	}
}

//
// Commands ---------------------------------------------------------------------------
//

// Attempt completion on the current word.
// Currently identitical to menu-complete.
func ( *Shell) () {
	.History.SkipSave()

	// This completion function should attempt to insert the first
	// valid completion found, without printing the actual list.
	if !.completer.IsActive() {
		.startMenuComplete(.commandCompletion)

		if .Config.GetBool("menu-complete-display-prefix") {
			return
		}
	}

	.completer.Select(1, 0)
	.completer.SkipDisplay()
}

// List possible completions for the current word.
func ( *Shell) () {
	.History.SkipSave()

	.startMenuComplete(.commandCompletion)
}

// Insert all completions for the current word into the line.
func ( *Shell) () {
	.History.Save()

	// Generate all possible completions
	if !.completer.IsActive() {
		.startMenuComplete(.commandCompletion)
	}

	// Insert each match, cancel insertion with preserving
	// the candidate just inserted in the line, for each.
	for  := 0;  < .completer.Matches(); ++ {
		.completer.Select(1, 0)
		.completer.Cancel(false, false)
	}

	// Clear the completion menu.
	.completer.Cancel(false, false)
	.completer.ClearMenu(true)
}

// Like complete-word, except that menu completion is used.
func ( *Shell) () {
	.History.SkipSave()

	// No completions are being printed yet, so simply generate the completions
	// as if we just request them without immediately selecting a candidate.
	if !.completer.IsActive() {
		.startMenuComplete(.commandCompletion)

		// Immediately select only if not asked to display first.
		if .Config.GetBool("menu-complete-display-prefix") {
			return
		}
	}

	.completer.Select(1, 0)
}

// Deletes the character under the cursor if not at the
// beginning or end of the line (like delete-char).
// If at the end of the line, behaves identically to
// possible-completions.
func ( *Shell) () {
	switch {
	case .cursor.Pos() < .line.Len():
		.line.CutRune(.cursor.Pos())
	default:
		.possibleCompletions()
	}
}

// Identical to menu-complete, but moves backward through the
// list of possible completions, as if menu-complete had been
// given a negative argument.
func ( *Shell) () {
	.History.SkipSave()

	// We don't do anything when not already completing.
	if !.completer.IsActive() {
		.startMenuComplete(.commandCompletion)
	}

	.completer.Select(-1, 0)
}

// In a menu completion, if there are several tags
// of completions, go to the first result of the next tag.
func ( *Shell) () {
	.History.SkipSave()

	if !.completer.IsActive() {
		return
	}

	.completer.SelectTag(true)
}

// In a menu completion, if there are several tags of
// completions, go to the first result of the previous tag.
func ( *Shell) () {
	.History.SkipSave()

	if !.completer.IsActive() {
		return
	}

	.completer.SelectTag(false)
}

// In a menu completion, insert the current completion
// into the buffer, and advance to the next possible completion.
func ( *Shell) () {
	.History.SkipSave()

	// We don't do anything when not already completing.
	if !.completer.IsActive() {
		return
	}

	// Also return if no candidate
	if !.completer.IsInserting() {
		return
	}

	// First insert the current candidate.
	.completer.Cancel(false, false)

	// And cycle to the next one.
	.completer.Select(1, 0)
}

// Open a completion menu (similar to menu-complete) with all currently populated Vim registers.
func ( *Shell) () {
	.History.SkipSave()
	.startMenuComplete(.Buffers.Complete)
}

// In a menu completion (whether a candidate is selected or not), start incremental-search
// (fuzzy search) on the results. Search backward incrementally for a specified string.
// The search is case-insensitive if the search string does not have uppercase letters
// and no numeric argument was given. The string may begin with ‘^’ to anchor the search
// to the beginning of the line. A restricted set of editing functions is available in the
// mini-buffer. Keys are looked up in the special isearch keymap, On each change in the
// mini-buffer, any currently selected candidate is dropped from the line and the menu.
// An interrupt signal, as defined by the stty setting, will stop the search and go back to the original line.
func ( *Shell) () {
	.History.SkipSave()

	// Always regenerate the list of completions.
	.completer.GenerateWith(.commandCompletion)
	.completer.IsearchStart("completions", false, false)
}

//
// Utilities --------------------------------------------------------------------------
//

// startMenuComplete generates a completion menu with completions
// generated from a given completer, without selecting a candidate.
func ( *Shell) ( completion.Completer) {
	.History.SkipSave()

	.Keymap.SetLocal(keymap.MenuSelect)
	.completer.GenerateWith()
}

// commandCompletion generates the completions for commands/args/flags.
func ( *Shell) () completion.Values {
	if .Completer == nil {
		return completion.Values{}
	}

	,  := .completer.Line()
	 := .Completer(*, .Pos())

	return .convert()
}

// historyCompletion manages the various completion/isearch modes related
// to history control. It can start the history completions, stop them, cycle
// through sources if more than one, and adjust the completion/isearch behavior.
func ( *Shell) (, ,  bool) {
	switch {
	case .Keymap.Local() == keymap.MenuSelect || .Keymap.Local() == keymap.Isearch || .completer.AutoCompleting():
		// If we are currently completing the last
		// history source, cancel history completion.
		if .History.OnLastSource() {
			.History.Cycle(true)
			.completer.ResetForce()
			.Hint.Reset()

			return
		}

		// Else complete the next history source.
		.History.Cycle(true)

		fallthrough

	default:
		// Notify if we don't have history sources at all.
		if .History.Current() == nil {
			.Hint.SetTemporary(fmt.Sprintf("%s%s%s %s", color.Dim, color.FgRed, "No command history source", color.Reset))
			return
		}

		// Generate the completions with specified behavior.
		 := func() completion.Values {
			 := .Display.AvailableHelperLines()
			return history.Complete(.History, , , , .completer.IsearchRegex)
		}

		if  {
			.completer.GenerateWith()
			.completer.IsearchStart(.History.Name(), true, true)
		} else {
			.startMenuComplete()
			.completer.AutocompleteForce()
		}
	}
}