<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/NeowayLabs/nash"
	"github.com/NeowayLabs/nash/sh"
	"github.com/chzyer/readline"
)

var runes = readline.Runes{}

type Completer struct {
	op   *readline.Operation
	term *readline.Terminal
	sh   *nash.Shell
}

func NewCompleter(op *readline.Operation, term *readline.Terminal, sh *nash.Shell) *Completer {
	return &Completer{op, term, sh}
}

func (c *Completer) Do(line []rune, pos int) ([][]rune, int) {
	var (
		newLine [][]rune
		offset  int
		lineArg = sh.NewStrObj(string(line))
		posArg  = sh.NewStrObj(strconv.Itoa(pos))
	)

	defer c.op.Refresh()
	defer c.term.PauseRead(false)

	nashFunc, ok := c.sh.GetFn("nash_complete")

	if !ok {
		// no complete available
		return [][]rune{[]rune{'\t'}}, offset
	}

	err := nashFunc.SetArgs([]sh.Obj{lineArg, posArg})

	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s", err.Error())
		return newLine, offset
	}

	nashFunc.SetStdin(c.sh.Stdin())
	nashFunc.SetStdout(c.sh.Stdout())
	nashFunc.SetStderr(c.sh.Stderr())

	if err = nashFunc.Start(); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s", err.Error())
		return newLine, offset
	}

	if err = nashFunc.Wait(); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s", err.Error())
		return newLine, offset
	}

	ret := nashFunc.Results()

	if ret == nil || ret.Type() != sh.ListType {
		fmt.Fprintf(os.Stderr, "ignoring autocomplete value: %v\n", ret)
		return newLine, offset
	}

	retlist := ret.(*sh.ListObj)

	if len(retlist.List()) != 2 {
		return newLine, pos
	}

	newline := retlist.List()[0]
	newpos := retlist.List()[1]

	if newline.Type() != sh.StringType || newpos.Type() != sh.StringType {
		fmt.Fprintf(os.Stderr, "ignoring autocomplete value: (%s) (%s)\n", newline, newpos)
		return newLine, offset
	}

	objline := newline.(*sh.StrObj)
	objpos := newpos.(*sh.StrObj)

	newoffset, err := strconv.Atoi(objpos.Str())

	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s", err.Error())
		return newLine, offset
	}

	newLine = append(newLine, []rune(objline.Str()))

	return newLine, newoffset
}<commit_msg>fix newline on err msgs<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/NeowayLabs/nash"
	"github.com/NeowayLabs/nash/sh"
	"github.com/chzyer/readline"
)

var runes = readline.Runes{}

type Completer struct {
	op   *readline.Operation
	term *readline.Terminal
	sh   *nash.Shell
}

func NewCompleter(op *readline.Operation, term *readline.Terminal, sh *nash.Shell) *Completer {
	return &Completer{op, term, sh}
}

func (c *Completer) Do(line []rune, pos int) ([][]rune, int) {
	var (
		newLine [][]rune
		offset  int
		lineArg = sh.NewStrObj(string(line))
		posArg  = sh.NewStrObj(strconv.Itoa(pos))
	)

	defer c.op.Refresh()
	defer c.term.PauseRead(false)

	nashFunc, ok := c.sh.GetFn("nash_complete")

	if !ok {
		// no complete available
		return [][]rune{[]rune{'\t'}}, offset
	}

	err := nashFunc.SetArgs([]sh.Obj{lineArg, posArg})

	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s\n", err.Error())
		return newLine, offset
	}

	nashFunc.SetStdin(c.sh.Stdin())
	nashFunc.SetStdout(c.sh.Stdout())
	nashFunc.SetStderr(c.sh.Stderr())

	if err = nashFunc.Start(); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s\n", err.Error())
		return newLine, offset
	}

	if err = nashFunc.Wait(); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s\n", err.Error())
		return newLine, offset
	}

	ret := nashFunc.Results()

	if ret == nil || ret.Type() != sh.ListType {
		fmt.Fprintf(os.Stderr, "ignoring autocomplete value: %v\n", ret)
		return newLine, offset
	}

	retlist := ret.(*sh.ListObj)

	if len(retlist.List()) != 2 {
		return newLine, pos
	}

	newline := retlist.List()[0]
	newpos := retlist.List()[1]

	if newline.Type() != sh.StringType || newpos.Type() != sh.StringType {
		fmt.Fprintf(os.Stderr, "ignoring autocomplete value: (%s) (%s)\n", newline, newpos)
		return newLine, offset
	}

	objline := newline.(*sh.StrObj)
	objpos := newpos.(*sh.StrObj)

	newoffset, err := strconv.Atoi(objpos.Str())

	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to autocomplete: %s\n", err.Error())
		return newLine, offset
	}

	newLine = append(newLine, []rune(objline.Str()))

	return newLine, newoffset
}
{'fraction_non_alphanumeric': 0.17274826789838338, 'fraction_numerical': 0.0013856812933025404, 'mean_word_length': 4.041909196740396, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '196060', 'n_tokens_mistral': 1835, 'n_tokens_neox': 1745, 'n_words': 366}