Fix issues with inputting and formatting multi line strings in ollama run
Co-authored-by: Wen Sun <iwendellsun@gmail.com>
This commit is contained in:
parent
82b9b329ff
commit
9fb5e8399c
3 changed files with 36 additions and 38 deletions
47
cmd/cmd.go
47
cmd/cmd.go
|
@ -602,14 +602,12 @@ func generateInteractive(cmd *cobra.Command, model string, wordWrap bool, format
|
||||||
fmt.Fprintln(os.Stderr, "")
|
fmt.Fprintln(os.Stderr, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt := readline.Prompt{
|
scanner, err := readline.New(readline.Prompt{
|
||||||
Prompt: ">>> ",
|
Prompt: ">>> ",
|
||||||
AltPrompt: "... ",
|
AltPrompt: "... ",
|
||||||
Placeholder: "Send a message (/? for help)",
|
Placeholder: "Send a message (/? for help)",
|
||||||
AltPlaceholder: `Use """ to end multi-line input`,
|
AltPlaceholder: `Use """ to end multi-line input`,
|
||||||
}
|
})
|
||||||
|
|
||||||
scanner, err := readline.New(prompt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -617,7 +615,7 @@ func generateInteractive(cmd *cobra.Command, model string, wordWrap bool, format
|
||||||
fmt.Print(readline.StartBracketedPaste)
|
fmt.Print(readline.StartBracketedPaste)
|
||||||
defer fmt.Printf(readline.EndBracketedPaste)
|
defer fmt.Printf(readline.EndBracketedPaste)
|
||||||
|
|
||||||
var multiLineBuffer string
|
var prompt string
|
||||||
|
|
||||||
for {
|
for {
|
||||||
line, err := scanner.Readline()
|
line, err := scanner.Readline()
|
||||||
|
@ -630,27 +628,33 @@ func generateInteractive(cmd *cobra.Command, model string, wordWrap bool, format
|
||||||
fmt.Println("\nUse Ctrl-D or /bye to exit.")
|
fmt.Println("\nUse Ctrl-D or /bye to exit.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scanner.Prompt.UseAlt = false
|
||||||
|
prompt = ""
|
||||||
|
|
||||||
continue
|
continue
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case scanner.Prompt.UseAlt:
|
case strings.HasPrefix(prompt, `"""`):
|
||||||
if strings.HasSuffix(line, `"""`) {
|
// if the prompt so far starts with """ then we're in multiline mode
|
||||||
scanner.Prompt.UseAlt = false
|
// and we need to keep reading until we find a line that ends with """
|
||||||
multiLineBuffer += strings.TrimSuffix(line, `"""`)
|
cut, found := strings.CutSuffix(line, `"""`)
|
||||||
line = multiLineBuffer
|
prompt += cut + "\n"
|
||||||
multiLineBuffer = ""
|
|
||||||
} else {
|
if !found {
|
||||||
multiLineBuffer += line + " "
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case strings.HasPrefix(line, `"""`):
|
|
||||||
|
prompt = strings.TrimPrefix(prompt, `"""`)
|
||||||
|
scanner.Prompt.UseAlt = false
|
||||||
|
case strings.HasPrefix(line, `"""`) && len(prompt) == 0:
|
||||||
scanner.Prompt.UseAlt = true
|
scanner.Prompt.UseAlt = true
|
||||||
multiLineBuffer = strings.TrimPrefix(line, `"""`) + " "
|
prompt += line + "\n"
|
||||||
|
continue
|
||||||
|
case scanner.Pasting:
|
||||||
|
prompt += line + "\n"
|
||||||
continue
|
continue
|
||||||
case strings.HasPrefix(line, "/list"):
|
case strings.HasPrefix(line, "/list"):
|
||||||
args := strings.Fields(line)
|
args := strings.Fields(line)
|
||||||
|
@ -757,12 +761,17 @@ func generateInteractive(cmd *cobra.Command, model string, wordWrap bool, format
|
||||||
case strings.HasPrefix(line, "/"):
|
case strings.HasPrefix(line, "/"):
|
||||||
args := strings.Fields(line)
|
args := strings.Fields(line)
|
||||||
fmt.Printf("Unknown command '%s'. Type /? for help\n", args[0])
|
fmt.Printf("Unknown command '%s'. Type /? for help\n", args[0])
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
prompt += line
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(line) > 0 && line[0] != '/' {
|
if len(prompt) > 0 && prompt[0] != '/' {
|
||||||
if err := generate(cmd, model, line, wordWrap, format); err != nil {
|
if err := generate(cmd, model, prompt, wordWrap, format); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prompt = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ type Instance struct {
|
||||||
Prompt *Prompt
|
Prompt *Prompt
|
||||||
Terminal *Terminal
|
Terminal *Terminal
|
||||||
History *History
|
History *History
|
||||||
|
Pasting bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(prompt Prompt) (*Instance, error) {
|
func New(prompt Prompt) (*Instance, error) {
|
||||||
|
@ -46,7 +47,7 @@ func New(prompt Prompt) (*Instance, error) {
|
||||||
|
|
||||||
func (i *Instance) Readline() (string, error) {
|
func (i *Instance) Readline() (string, error) {
|
||||||
prompt := i.Prompt.Prompt
|
prompt := i.Prompt.Prompt
|
||||||
if i.Prompt.UseAlt {
|
if i.Prompt.UseAlt || i.Pasting {
|
||||||
prompt = i.Prompt.AltPrompt
|
prompt = i.Prompt.AltPrompt
|
||||||
}
|
}
|
||||||
fmt.Print(prompt)
|
fmt.Print(prompt)
|
||||||
|
@ -63,12 +64,13 @@ func (i *Instance) Readline() (string, error) {
|
||||||
var esc bool
|
var esc bool
|
||||||
var escex bool
|
var escex bool
|
||||||
var metaDel bool
|
var metaDel bool
|
||||||
var pasteMode PasteMode
|
|
||||||
|
|
||||||
var currentLineBuf []rune
|
var currentLineBuf []rune
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if buf.IsEmpty() {
|
// don't show placeholder when pasting unless we're in multiline mode
|
||||||
|
showPlaceholder := !i.Pasting || i.Prompt.UseAlt
|
||||||
|
if buf.IsEmpty() && showPlaceholder {
|
||||||
ph := i.Prompt.Placeholder
|
ph := i.Prompt.Placeholder
|
||||||
if i.Prompt.UseAlt {
|
if i.Prompt.UseAlt {
|
||||||
ph = i.Prompt.AltPlaceholder
|
ph = i.Prompt.AltPlaceholder
|
||||||
|
@ -119,9 +121,9 @@ func (i *Instance) Readline() (string, error) {
|
||||||
code += string(r)
|
code += string(r)
|
||||||
}
|
}
|
||||||
if code == CharBracketedPasteStart {
|
if code == CharBracketedPasteStart {
|
||||||
pasteMode = PasteModeStart
|
i.Pasting = true
|
||||||
} else if code == CharBracketedPasteEnd {
|
} else if code == CharBracketedPasteEnd {
|
||||||
pasteMode = PasteModeEnd
|
i.Pasting = false
|
||||||
}
|
}
|
||||||
case KeyDel:
|
case KeyDel:
|
||||||
if buf.Size() > 0 {
|
if buf.Size() > 0 {
|
||||||
|
@ -196,12 +198,7 @@ func (i *Instance) Readline() (string, error) {
|
||||||
}
|
}
|
||||||
buf.MoveToEnd()
|
buf.MoveToEnd()
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
switch pasteMode {
|
|
||||||
case PasteModeStart:
|
|
||||||
output = `"""` + output
|
|
||||||
case PasteModeEnd:
|
|
||||||
output = output + `"""`
|
|
||||||
}
|
|
||||||
return output, nil
|
return output, nil
|
||||||
default:
|
default:
|
||||||
if metaDel {
|
if metaDel {
|
||||||
|
|
|
@ -76,11 +76,3 @@ const (
|
||||||
CharBracketedPasteStart = "00~"
|
CharBracketedPasteStart = "00~"
|
||||||
CharBracketedPasteEnd = "01~"
|
CharBracketedPasteEnd = "01~"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PasteMode int
|
|
||||||
|
|
||||||
const (
|
|
||||||
PastModeOff = iota
|
|
||||||
PasteModeStart
|
|
||||||
PasteModeEnd
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in a new issue