github.com/jmigpin/editor@v1.6.0/core/contentcmd.go (about)

     1  package core
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  )
     8  
     9  type ContentCmd struct {
    10  	Name string // for removal and error msgs
    11  	Fn   ContentCmdFn
    12  }
    13  
    14  type ContentCmdFn func(ctx context.Context, erow *ERow, index int) (_ error, handled bool)
    15  
    16  //----------
    17  
    18  type contentCmds []*ContentCmd
    19  
    20  func (ccs *contentCmds) Append(name string, fn ContentCmdFn) {
    21  	cc := &ContentCmd{name, fn}
    22  	*ccs = append(*ccs, cc)
    23  }
    24  
    25  func (ccs *contentCmds) Prepend(name string, fn ContentCmdFn) {
    26  	cc := &ContentCmd{name, fn}
    27  	*ccs = append([]*ContentCmd{cc}, *ccs...)
    28  }
    29  
    30  func (ccs *contentCmds) Remove(name string) (removed bool) {
    31  	var a []*ContentCmd
    32  	for _, cc := range *ccs {
    33  		if cc.Name == name {
    34  			removed = true
    35  		} else {
    36  			a = append(a, cc)
    37  		}
    38  	}
    39  	*ccs = a
    40  	return
    41  }
    42  
    43  //----------
    44  
    45  // global cmds added via init() from "contentcmds" pkg
    46  var ContentCmds contentCmds
    47  
    48  func runContentCmds(ctx context.Context, erow *ERow, index int) {
    49  	errs := []string{}
    50  	for _, cc := range ContentCmds {
    51  		err, handled := cc.Fn(ctx, erow, index)
    52  		if handled {
    53  			if err != nil {
    54  				s := fmt.Sprintf("%v: %v", cc.Name, err)
    55  				errs = append(errs, s)
    56  			} else {
    57  				// stop on first handled without error
    58  				return
    59  			}
    60  		}
    61  	}
    62  
    63  	u := strings.Join(errs, "\n\t")
    64  	if len(u) > 0 {
    65  		u = "\n\t" + u
    66  	}
    67  	erow.Ed.Errorf("no content cmd ran successfully%v", u)
    68  }
    69  
    70  func ContentCmdFromTextArea(erow *ERow, index int) {
    71  	erow.Ed.RunAsyncBusyCursor(erow.Row, func(done func()) {
    72  		defer done()
    73  		ctx, cancel := erow.newContentCmdCtx()
    74  		defer cancel()
    75  		runContentCmds(ctx, erow, index)
    76  	})
    77  }