package complete

import (
	
	
	
	
	

	
	
	
	
	
)

var pathSeparator = string(filepath.Separator)

// GenerateFileNames returns filename candidates that are suitable for completing
// the last argument. It can be used in Config.ArgGenerator.
func ( []string) ([]RawItem, error) {
	return generateFileNames([len()-1], false)
}

// GenerateForSudo generates candidates for sudo.
func ( Config,  []string) ([]RawItem, error) {
	switch {
	case len() < 2:
		return nil, errNoCompletion
	case len() == 2:
		// Complete external commands.
		return generateExternalCommands([1], .PureEvaler)
	default:
		return .ArgGenerator([1:])
	}
}

// Internal generators, used from completers.

func ( string,  PureEvaler) ([]RawItem, error) {
	if fsutil.DontSearch() {
		// Completing a local external command name.
		return generateFileNames(, true)
	}
	var  []RawItem
	.EachExternal(func( string) {  = append(, PlainItem()) })
	return , nil
}

func ( string,  PureEvaler) ([]RawItem, error) {
	if fsutil.DontSearch() {
		// Completing a local external command name.
		return generateFileNames(, true)
	}

	var  []RawItem
	 := func( string) {  = append(, PlainItem()) }

	if strings.HasPrefix(, "e:") {
		// Generate all external commands with the e: prefix, and be done.
		.EachExternal(func( string) {
			("e:" + )
		})
		return , nil
	}

	// Generate all special forms.
	.EachSpecial()
	// Generate all external commands (without the e: prefix).
	.EachExternal()

	,  := eval.SplitSigil()
	,  := eval.SplitIncompleteQNameNs()
	if  == "" {
		// Generate functions, namespaces, and variable assignments.
		.EachVariableInNs(, func( string) {
			switch {
			case strings.HasSuffix(, eval.FnSuffix):
				(
					 + [:len()-len(eval.FnSuffix)])
			case strings.HasSuffix(, eval.NsSuffix):
				( + )
			default:
				 = append(, noQuoteItem(++" = "))
			}
		})
	}

	return , nil
}

func ( string,  bool) ([]RawItem, error) {
	var  []RawItem

	,  := filepath.Split()
	 := 
	if  == "" {
		 = "."
	}

	,  := ioutil.ReadDir()
	if  != nil {
		return nil, fmt.Errorf("cannot list directory %s: %v", , )
	}

	 := lscolors.GetColorist()

	// Make candidates out of elements that match the file component.
	for ,  := range  {
		 := .Name()
		// Show dot files iff file part of pattern starts with dot, and vice
		// versa.
		if dotfile() != dotfile() {
			continue
		}
		// Only accept searchable directories and executable files if
		// executableOnly is true.
		if  && (.Mode()&0111) == 0 {
			continue
		}

		// Full filename for source and getStyle.
		 :=  + 

		// Will be set to an empty space for non-directories
		 := " "

		if .IsDir() {
			 += pathSeparator
			 = ""
		} else if .Mode()&os.ModeSymlink != 0 {
			,  := os.Stat()
			if  == nil && .IsDir() {
				// Symlink to directory.
				 += pathSeparator
				 = ""
			}
		}

		 = append(, ComplexItem{
			Stem:         ,
			CodeSuffix:   ,
			DisplayStyle: ui.StyleFromSGR(.GetStyle()),
		})
	}

	return , nil
}

func ( interface{}) []RawItem {
	var  []RawItem
	vals.IterateKeys(, func( interface{}) bool {
		if ,  := .(string);  {
			 = append(, PlainItem())
		}
		return true
	})
	return 
}

func ( string) bool {
	return strings.HasPrefix(, ".")
}