package complete
import (
)
var parent = parse.Parent
var completers = []completer{
completeCommand,
completeIndex,
completeRedir,
completeVariable,
completeArg,
}
type completer func(parse.Node, Config) (*context, []RawItem, error)
type context struct {
name string
seed string
quote parse.PrimaryType
interval diag.Ranging
}
func ( parse.Node, Config) (*context, []RawItem, error) {
:= .PureEvaler
if , := .(*parse.Sep); {
if , := parent().(*parse.Form); && .Head != nil {
:= &context{"argument", "", parse.Bareword, range0(.Range().To)}
:= purelyEvalForm(, "", .Range().To, )
, := .ArgGenerator()
return , ,
}
}
if , := .(*parse.Primary); {
if , := primaryInSimpleCompound(, ); != nil {
if , := parent().(*parse.Form); {
if .Head != nil && .Head != {
:= &context{"argument", , .Type, .Range()}
:= purelyEvalForm(, , .Range().From, )
, := .ArgGenerator()
return , ,
}
}
}
}
return nil, nil, errNoCompletion
}
func ( parse.Node, Config) (*context, []RawItem, error) {
:= .PureEvaler
:= func( int) (*context, []RawItem, error) {
:= &context{"command", "", parse.Bareword, range0()}
, := generateCommands("", )
return , ,
}
if is(, aChunk) {
return (.Range().To)
}
if is(, aSep) {
:= parent()
switch {
case is(, aChunk), is(, aPipeline):
return (.Range().To)
case is(, aPrimary):
:= .(*parse.Primary).Type
if == parse.OutputCapture || == parse.ExceptionCapture {
return (.Range().To)
}
}
}
if , := .(*parse.Primary); {
if , := primaryInSimpleCompound(, ); != nil {
if , := parent().(*parse.Form); {
if .Head == {
:= &context{
"command", , .Type, .Range()}
, := generateCommands(, )
return , ,
}
}
}
}
return nil, nil, errNoCompletion
}
func ( parse.Node, Config) (*context, []RawItem, error) {
:= .PureEvaler
:= func( interface{}, int) (*context, []RawItem, error) {
:= &context{"index", "", parse.Bareword, range0()}
return , generateIndices(), nil
}
if is(, aSep) {
if is(parent(), aIndexing) {
:= parent().(*parse.Indexing)
if len(.Indicies) == 1 {
if := .PurelyEvalPrimary(.Head); != nil {
return (, .Range().To)
}
}
}
if is(parent(), aArray) {
:= parent()
if is(parent(), aIndexing) {
:= parent().(*parse.Indexing)
if len(.Indicies) == 1 {
if := .PurelyEvalPrimary(.Head); != nil {
return (, .Range().To)
}
}
}
}
}
if is(, aPrimary) {
:= .(*parse.Primary)
, := primaryInSimpleCompound(, )
if != nil {
if is(parent(), aArray) {
:= parent()
if is(parent(), aIndexing) {
:= parent().(*parse.Indexing)
if len(.Indicies) == 1 {
if := .PurelyEvalPrimary(.Head); != nil {
:= &context{
"index", , .Type, .Range()}
return , generateIndices(), nil
}
}
}
}
}
}
return nil, nil, errNoCompletion
}
func ( parse.Node, Config) (*context, []RawItem, error) {
:= .PureEvaler
if is(, aSep) {
if is(parent(), aRedir) {
:= &context{"redir", "", parse.Bareword, range0(.Range().To)}
, := generateFileNames("", false)
return , ,
}
}
if , := .(*parse.Primary); {
if , := primaryInSimpleCompound(, ); != nil {
if is(parent(), &parse.Redir{}) {
:= &context{
"redir", , .Type, .Range()}
, := generateFileNames(, false)
return , ,
}
}
}
return nil, nil, errNoCompletion
}
func ( parse.Node, Config) (*context, []RawItem, error) {
:= .PureEvaler
, := .(*parse.Primary)
if ! || .Type != parse.Variable {
return nil, nil, errNoCompletion
}
, := eval.SplitSigil(.Value)
, := eval.SplitIncompleteQNameNs()
:= .Range().From + 1 + len() + len()
:= &context{
"variable", , parse.Bareword,
diag.Ranging{From: , To: .Range().To}}
var []RawItem
.EachVariableInNs(, func( string) {
= append(, noQuoteItem(parse.QuoteVariableName()))
})
.EachNs(func( string) {
if hasProperPrefix(, ) {
= append(, noQuoteItem(parse.QuoteVariableName([len():])))
}
})
return , , nil
}
func ( int) diag.Ranging {
return diag.Ranging{From: , To: }
}
func (, string) bool {
return len() > len() && strings.HasPrefix(, )
}