github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/cmds/elvish/edit/completion/complete_index.go (about)

     1  package completion
     2  
     3  import (
     4  	"github.com/u-root/u-root/cmds/elvish/eval/vals"
     5  	"github.com/u-root/u-root/cmds/elvish/parse"
     6  )
     7  
     8  type indexComplContext struct {
     9  	complContextCommon
    10  	indexee interface{}
    11  }
    12  
    13  func (*indexComplContext) name() string { return "index" }
    14  
    15  // Find context information for complIndex.
    16  //
    17  // Right now we only support cases where there is only one level of indexing,
    18  // e.g. $a[<Tab> is supported but $a[x][<Tab> is not.
    19  func findIndexComplContext(n parse.Node, ev pureEvaler) complContext {
    20  	if parse.IsSep(n) {
    21  		if parse.IsIndexing(n.Parent()) {
    22  			// We are just after an opening bracket.
    23  			indexing := parse.GetIndexing(n.Parent())
    24  			if len(indexing.Indicies) == 1 {
    25  				if indexee := ev.PurelyEvalPrimary(indexing.Head); indexee != nil {
    26  					return &indexComplContext{
    27  						complContextCommon{
    28  							"", quotingForEmptySeed, n.End(), n.End()},
    29  						indexee,
    30  					}
    31  				}
    32  			}
    33  		}
    34  		if parse.IsArray(n.Parent()) {
    35  			array := n.Parent()
    36  			if parse.IsIndexing(array.Parent()) {
    37  				// We are after an existing index and spaces.
    38  				indexing := parse.GetIndexing(array.Parent())
    39  				if len(indexing.Indicies) == 1 {
    40  					if indexee := ev.PurelyEvalPrimary(indexing.Head); indexee != nil {
    41  						return &indexComplContext{
    42  							complContextCommon{
    43  								"", quotingForEmptySeed, n.End(), n.End()},
    44  							indexee,
    45  						}
    46  					}
    47  				}
    48  			}
    49  		}
    50  	}
    51  
    52  	if parse.IsPrimary(n) {
    53  		primary := parse.GetPrimary(n)
    54  		compound, seed := primaryInSimpleCompound(primary, ev)
    55  		if compound != nil {
    56  			if parse.IsArray(compound.Parent()) {
    57  				array := compound.Parent()
    58  				if parse.IsIndexing(array.Parent()) {
    59  					// We are just after an incomplete index.
    60  					indexing := parse.GetIndexing(array.Parent())
    61  					if len(indexing.Indicies) == 1 {
    62  						if indexee := ev.PurelyEvalPrimary(indexing.Head); indexee != nil {
    63  							return &indexComplContext{
    64  								complContextCommon{
    65  									seed, primary.Type, compound.Begin(), compound.End()},
    66  								indexee,
    67  							}
    68  						}
    69  					}
    70  				}
    71  			}
    72  		}
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  func (ctx *indexComplContext) generate(env *complEnv, ch chan<- rawCandidate) error {
    79  	return vals.IterateKeys(ctx.indexee, func(k interface{}) bool {
    80  		if kstring, ok := k.(string); ok {
    81  			ch <- plainCandidate(kstring)
    82  		}
    83  		return true
    84  	})
    85  }