github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/shell/prompt.go (about)

     1  package shell
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/lmorg/murex/app"
     7  	"github.com/lmorg/murex/lang"
     8  	"github.com/lmorg/murex/lang/types"
     9  	"github.com/lmorg/murex/utils"
    10  	"github.com/lmorg/murex/utils/ansititle"
    11  )
    12  
    13  func getPrompt() []byte {
    14  	var (
    15  		err, err2 error
    16  		exitNum   int
    17  		b         []byte
    18  	)
    19  
    20  	prompt, fileRef, err := lang.ShellProcess.Config.GetFileRef("shell", "prompt", types.CodeBlock)
    21  	if err == nil {
    22  		fork := lang.ShellProcess.Fork(lang.F_FUNCTION | lang.F_BACKGROUND | lang.F_NO_STDIN | lang.F_CREATE_STDOUT | lang.F_NO_STDERR)
    23  		fork.Variables.Set(fork.Process, "linenum", 1, types.Integer)
    24  		fork.Name.Set("(prompt)")
    25  		fork.FileRef = fileRef
    26  		fork.Execute([]rune(prompt.(string)))
    27  
    28  		b, err2 = fork.Stdout.ReadAll()
    29  		b = utils.CrLfTrim(b)
    30  	}
    31  
    32  	if exitNum != 0 || err != nil || len(b) == 0 || err2 != nil {
    33  		lang.ShellProcess.Stderr.Writeln([]byte("Invalid prompt. Block returned false."))
    34  		b = []byte("murex » ")
    35  	}
    36  
    37  	return b
    38  }
    39  
    40  func getMultilinePrompt(nLines int) []byte {
    41  	var (
    42  		err, err2 error
    43  		exitNum   int
    44  		b         []byte
    45  	)
    46  
    47  	prompt, fileRef, err := lang.ShellProcess.Config.GetFileRef("shell", "prompt-multiline", types.CodeBlock)
    48  	if err == nil {
    49  		fork := lang.ShellProcess.Fork(lang.F_FUNCTION | lang.F_BACKGROUND | lang.F_NO_STDIN | lang.F_CREATE_STDOUT | lang.F_NO_STDERR)
    50  		fork.Variables.Set(fork.Process, "linenum", nLines, types.Integer)
    51  		fork.Name.Set("(prompt-multiline)")
    52  		fork.FileRef = fileRef
    53  		fork.Execute([]rune(prompt.(string)))
    54  
    55  		b, err2 = fork.Stdout.ReadAll()
    56  		b = utils.CrLfTrim(b)
    57  	}
    58  
    59  	if exitNum != 0 || err != nil || len(b) == 0 || err2 != nil {
    60  		lang.ShellProcess.Stderr.Writeln([]byte("Invalid prompt. Block returned false."))
    61  		b = []byte(fmt.Sprintf("%5d » ", nLines))
    62  	}
    63  
    64  	return b
    65  }
    66  
    67  func writeTitlebar() {
    68  	v, fileRef, err := lang.ShellProcess.Config.GetFileRef("shell", "titlebar-func", types.CodeBlock)
    69  	title, ok := v.(string)
    70  	if !ok || err != nil || title == `out: ''` {
    71  		return
    72  	}
    73  
    74  	fork := lang.ShellProcess.Fork(lang.F_FUNCTION | lang.F_BACKGROUND | lang.F_NO_STDIN | lang.F_CREATE_STDOUT | lang.F_NO_STDERR)
    75  	fork.Name.Set("(titlebar-func)")
    76  	fork.FileRef = fileRef
    77  	exitNum, err := fork.Execute([]rune(title))
    78  
    79  	var b []byte
    80  	if err == nil {
    81  		b, err = fork.Stdout.ReadAll()
    82  		b = utils.CrLfTrim(b)
    83  	}
    84  
    85  	if exitNum != 0 || err != nil {
    86  		lang.ShellProcess.Stderr.Writeln([]byte(fmt.Sprintf("Invalid titlebar-func: %V", err)))
    87  		ansititle.Write([]byte(app.Name))
    88  	}
    89  
    90  	ansititle.Write(b)
    91  }
    92  
    93  // ConfigReadGetCursorPos is a dynamic config wrapper function for Prompt.EnableGetCursorPos
    94  func ConfigReadGetCursorPos() (interface{}, error) {
    95  	return Prompt.EnableGetCursorPos, nil
    96  }
    97  
    98  // ConfigWriteGetCursorPos is a dynamic config wrapper function for Prompt.EnableGetCursorPos
    99  func ConfigWriteGetCursorPos(v interface{}) error {
   100  	switch v := v.(type) {
   101  	case bool:
   102  		Prompt.EnableGetCursorPos = v
   103  
   104  	case string:
   105  		switch v {
   106  		case types.TrueString:
   107  			Prompt.EnableGetCursorPos = true
   108  
   109  		case types.FalseString:
   110  			Prompt.EnableGetCursorPos = false
   111  
   112  		default:
   113  			return fmt.Errorf("expecting 'true' or 'false'. Instead received '%s'", v)
   114  		}
   115  
   116  	default:
   117  		return fmt.Errorf("expecting boolean value. Instead received %T", v)
   118  	}
   119  
   120  	return nil
   121  }