github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/events/onPrompt/onprompt.go (about)

     1  package onprompt
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	"github.com/lmorg/murex/builtins/events"
     8  	"github.com/lmorg/murex/lang"
     9  	"github.com/lmorg/murex/lang/ref"
    10  	"github.com/lmorg/murex/shell"
    11  	"github.com/lmorg/murex/utils/lists"
    12  )
    13  
    14  var eventType = "onPrompt"
    15  
    16  func init() {
    17  	event := newOnPrompt()
    18  	events.AddEventType(eventType, event, nil)
    19  	shell.Events = event.callback
    20  }
    21  
    22  // Interrupt is a JSONable structure passed to the murex function
    23  type Interrupt struct {
    24  	Name      string
    25  	Operation string
    26  	CmdLine   string
    27  }
    28  
    29  type promptEvent struct {
    30  	Key     string
    31  	Block   []rune
    32  	FileRef *ref.File
    33  }
    34  
    35  type promptEvents struct {
    36  	events []promptEvent
    37  	//mutex  sync.Mutex
    38  }
    39  
    40  func newOnPrompt() *promptEvents {
    41  	return new(promptEvents)
    42  }
    43  
    44  // Add a command to the onPrompt
    45  func (evt *promptEvents) Add(name, interrupt string, block []rune, fileRef *ref.File) error {
    46  	if err := isValidInterrupt(interrupt); err != nil {
    47  		return err
    48  	}
    49  
    50  	//evt.mutex.Lock()
    51  
    52  	key := compileInterruptKey(interrupt, name)
    53  	event := promptEvent{
    54  		Key:     key,
    55  		Block:   block,
    56  		FileRef: fileRef,
    57  	}
    58  
    59  	i := evt.exists(key)
    60  	if i == doesNotExist {
    61  		evt.events = append(evt.events, event)
    62  		sort.SliceStable(evt.events, func(i, j int) bool {
    63  			return evt.events[i].Key < evt.events[j].Key
    64  		})
    65  	} else {
    66  		evt.events[i] = event
    67  	}
    68  
    69  	//evt.mutex.Unlock()
    70  
    71  	return nil
    72  }
    73  
    74  func (evt *promptEvents) Remove(key string) error {
    75  	//evt.mutex.Lock()
    76  	//defer evt.mutex.Unlock()
    77  
    78  	i := evt.exists(key)
    79  	if i != doesNotExist {
    80  		events, err := lists.RemoveOrdered(evt.events, i)
    81  		if err != nil {
    82  			return fmt.Errorf("unable to remove %s: %s", key, err.Error())
    83  		}
    84  		evt.events = events
    85  		return nil
    86  	}
    87  
    88  	var success bool
    89  	for _, interrupt := range interrupts {
    90  		newKey := compileInterruptKey(interrupt, key)
    91  		i = evt.exists(newKey)
    92  		if i != doesNotExist {
    93  			events, err := lists.RemoveOrdered(evt.events, i)
    94  			if err != nil {
    95  				return fmt.Errorf("unable to remove %s: %s", newKey, err.Error())
    96  			}
    97  			evt.events = events
    98  			success = true
    99  		}
   100  	}
   101  
   102  	if success {
   103  		return nil
   104  	}
   105  	return fmt.Errorf("no %s event found called `%s`", eventType, key)
   106  }
   107  
   108  func (evt *promptEvents) callback(interrupt string, cmdLine []rune) {
   109  	if err := isValidInterrupt(interrupt); err != nil {
   110  		panic(err.Error())
   111  	}
   112  
   113  	//evt.mutex.Lock()
   114  
   115  	for i := range evt.events {
   116  		split := getInterruptFromKey(evt.events[i].Key)
   117  		if split[0] == interrupt {
   118  			interruptValue := Interrupt{
   119  				Name:      split[1],
   120  				Operation: interrupt,
   121  				CmdLine:   string(cmdLine),
   122  			}
   123  			events.Callback(evt.events[i].Key, interruptValue, evt.events[i].Block, evt.events[i].FileRef, lang.ShellProcess.Stdout, false)
   124  		}
   125  	}
   126  
   127  	//evt.mutex.Unlock()
   128  }
   129  
   130  const doesNotExist = -1
   131  
   132  func (evt *promptEvents) exists(key string) int {
   133  	//evt.mutex.Lock()
   134  
   135  	for i := range evt.events {
   136  		if evt.events[i].Key == key {
   137  			return i
   138  		}
   139  	}
   140  
   141  	//evt.mutex.Unlock()
   142  
   143  	return doesNotExist
   144  }
   145  
   146  func (evt *promptEvents) Dump() map[string]events.DumpT {
   147  	dump := make(map[string]events.DumpT)
   148  
   149  	//evt.mutex.Lock()
   150  
   151  	for i := range evt.events {
   152  		dump[evt.events[i].Key] = events.DumpT{
   153  			Interrupt: getInterruptFromKey(evt.events[i].Key)[0],
   154  			Block:     string(evt.events[i].Block),
   155  			FileRef:   evt.events[i].FileRef,
   156  		}
   157  	}
   158  
   159  	//evt.mutex.Unlock()
   160  
   161  	return dump
   162  }