Example #1
0
func (i *cli) ReadString(delim byte) (line string, err error) {
	system.SetForegroundGroup(system.Pgid())

	uncooked.ApplyMode()
	defer cooked.ApplyMode()

	command := cell.List(
		cell.Cons(
			cell.NewSymbol("_sys_"),
			cell.NewSymbol("get-prompt"),
		),
		cell.NewSymbol("> "),
	)
	prompt := task.Call(nil, command, "")

	if line, err = i.State.Prompt(prompt); err == nil {
		i.AppendHistory(line)
		if task.ForegroundTask().Job.Command == "" {
			task.ForegroundTask().Job.Command = line
		}
		line += "\n"
	}

	if err == liner.ErrPromptAborted {
		return line, cell.ErrCtrlCPressed
	}

	return
}
Example #2
0
func (i *cli) ReadString(delim byte) (line string, err error) {
	task.SetForegroundGroup(task.Pgid())

	uncooked.ApplyMode()
	defer cooked.ApplyMode()

	if line, err = i.State.Prompt(task.Pgid(), "> "); err == nil {
		i.AppendHistory(line)
		if task.ForegroundTask().Job.Command == "" {
			task.ForegroundTask().Job.Command = line
		}
		line += "\n"
	}
	return
}
Example #3
0
func complete(line string, pos int) (head string, completions []string, tail string) {
	first, state, completing := task.GlobalParser().State(line[:pos])

	head = line[:pos]
	tail = line[pos:]

	defer func() {
		r := recover()
		if r == nil {
			return
		}

		completions = []string{}
	}()

	if state == "SkipWhitespace" {
		return head, []string{"    "}, tail
	}

	if !strings.HasSuffix(head, completing) {
		return head, []string{}, tail
	}

	// Ensure line == prefix + completing + tail
	prefix := head[0 : len(head)-len(completing)]

	if first == "" {
		completions = executables(completing)
	} else {
		completions = files(completing)
	}

	completions = append(
		completions,
		task.ForegroundTask().Complete(first, completing)...,
	)

	if len(completions) == 0 {
		return prefix, []string{completing}, tail
	}

	unique := make(map[string]bool)
	for _, completion := range completions {
		unique[completion] = true
	}

	completions = make([]string, 0, len(unique))
	for completion := range unique {
		completions = append(completions, completion)
	}

	return prefix, completions, tail
}
Example #4
0
func complete(line string, pos int) (string, []string, string) {
	head := line[:pos]
	tail := line[pos:]

	fields := strings.Fields(head)

	if len(fields) == 0 {
		return head, []string{"    "}, tail
	}

	word := fields[len(fields)-1]
	if !strings.HasSuffix(head, word) {
		return head, []string{}, tail
	}

	head = head[0 : len(head)-len(word)]

	completions := task.ForegroundTask().Complete(word)
	completions = append(completions, files(word)...)
	if len(fields) == 1 {
		completions = append(completions, executables(word)...)
	}

	if len(completions) == 0 {
		return head, []string{word}, tail
	}

	unique := make(map[string]bool)
	for _, completion := range completions {
		unique[completion] = true
	}

	completions = make([]string, 0, len(unique))
	for completion := range unique {
		completions = append(completions, completion)
	}

	return head, completions, tail
}
Example #5
0
File: ui.go Project: ivanfoo/oh
func (i *cli) ReadString(delim byte) (line string, err error) {
	task.SetForegroundGroup(task.Pgid())

	uncooked.ApplyMode()
	defer cooked.ApplyMode()

	t := task.ForegroundTask()

	command := cell.List(
		cell.Cons(cell.NewSymbol("sys"), cell.NewSymbol("get-prompt")),
		cell.NewSymbol("> "),
	)
	prompt := t.Call(command)

	if line, err = i.State.Prompt(prompt); err == nil {
		i.AppendHistory(line)
		if t.Job.Command == "" {
			t.Job.Command = line
		}
		line += "\n"
	}
	return
}
Example #6
0
func files(word string) []string {
	completions := []string{}

	candidate := word
	if candidate[:1] == "~" {
		candidate = filepath.Join(os.Getenv("HOME"), candidate[1:])
	}

	candidate = path.Clean(candidate)
	if !path.IsAbs(candidate) {
		ft := task.ForegroundTask()
		n := cell.NewSymbol("$cwd")
		ref := task.Resolve(ft.Lexical, ft.Dynamic, n)
		cwd := ref.Get().String()

		candidate = path.Join(cwd, candidate)
	}

	dirname, basename := filepath.Split(candidate)
	if strings.HasSuffix(word, "/") {
		dirname, basename = path.Join(dirname, basename)+"/", ""
	}

	stat, err := os.Stat(dirname)
	if err != nil {
		return completions
	} else if len(basename) == 0 && !stat.IsDir() {
		return completions
	}

	max := strings.Count(dirname, "/")

	filepath.Walk(dirname, func(p string, i os.FileInfo, err error) error {
		depth := strings.Count(p, "/")
		if depth > max {
			if i.IsDir() {
				return filepath.SkipDir
			}
			return nil
		} else if depth < max {
			return nil
		}

		full := path.Join(dirname, basename)
		if len(basename) == 0 {
			if p == dirname {
				return nil
			}
			full += "/"
		} else if !strings.HasPrefix(p, full) {
			return nil
		}

		if i.IsDir() {
			p += "/"
		}

		if len(full) >= len(p) {
			return nil
		}

		completion := word + p[len(full):]
		completions = append(completions, completion)

		return nil
	})

	return completions
}