示例#1
0
文件: cli.go 项目: alexcrichton/fargo
//export rawComplete
func rawComplete(ctext *C.char, a int, b int) **C.char {
	/* a, b are the limits of ctext in rl_line_buffer, so if a == 0 then we're
	 * completing a command, otherwise the argument to a command */
	text := C.GoString(ctext)
	if a == 0 {
		completionResults = filter(commands, text)
	} else {
		line := C.GoString(C.rl_line_buffer)
		idx := strings.Index(line, " ")
		if idx > 0 {
			completionResults = activeTerm.complete(line[0:idx], line[idx+1:])
		} else {
			completionResults = nil
		}
	}

	/* if we're finishing a completion with one entry that's a directory, don't
	 * append the ' ' character at the end to continue completion */
	if len(completionResults) == 1 {
		if strings.HasSuffix(completionResults[0], "/") {
			C.rl_completion_suppress_append = 1
		}
	}
	return C.rl_completion_matches(ctext, C.fargo_completion_entry)
}
示例#2
0
//export minicliCompletion
//
// From readline documentation:
// Returns an array of (char *) which is a list of completions for text. If
// there are no completions, returns (char **)NULL. The first entry in the
// returned array is the substitution for text. The remaining entries are the
// possible completions. The array is terminated with a NULL pointer.
func minicliCompletion(text *C.char, start, end C.int) **C.char {
	// Determine the size of a pointer on the current system
	var b *C.char
	ptrSize := unsafe.Sizeof(b)

	// Copy the buffer containing the line so far
	line := C.GoString(C.rl_line_buffer)

	// Default is to not change the string
	vals := []string{C.GoString(text)}

	// Generate suggestions
	suggest := minicli.Suggest(line)

	if len(suggest) == 1 {
		// Use only suggestion as substitution for text
		vals[0] = suggest[0]
	} else if len(suggest) == 0 {
		// No suggestions.. fall back on default behavior (filename completion)
		return C.rl_completion_matches(text,
			(*C.rl_compentry_func_t)(C.rl_filename_completion_function))
	}
	vals = append(vals, suggest...)

	// Copy suggestions into char**
	ptr := C.malloc(C.size_t(len(vals)+1) * C.size_t(ptrSize))
	for i, v := range vals {
		element := (**C.char)(unsafe.Pointer(uintptr(ptr) + uintptr(i)*ptrSize))
		*element = C.CString(v)
	}
	element := (**C.char)(unsafe.Pointer(uintptr(ptr) + uintptr(len(vals))*ptrSize))
	*element = nil

	return (**C.char)(ptr)
}
示例#3
0
func CompletionMatches(text string, cbk func(text string, state int) string) []string {
	c_text := C.CString(text)
	defer C.free(unsafe.Pointer(c_text))
	c_cbk := (*C.rl_compentry_func_t)(unsafe.Pointer(&cbk))
	c_matches := C.rl_completion_matches(c_text, c_cbk)
	n_matches := int(C._go_readline_strarray_len(c_matches))
	matches := make([]string, n_matches)
	for i := 0; i < n_matches; i++ {
		matches[i] = C.GoString(C._go_readline_strarray_at(c_matches, C.int(i)))
	}
	return matches
}
示例#4
0
//export minicliCompletion
//
// From readline documentation:
// Returns an array of (char *) which is a list of completions for text. If
// there are no completions, returns (char **)NULL. The first entry in the
// returned array is the substitution for text. The remaining entries are the
// possible completions. The array is terminated with a NULL pointer.
func minicliCompletion(text *C.char, start, end C.int) **C.char {
	// Determine the size of a pointer on the current system
	var b *C.char
	ptrSize := unsafe.Sizeof(b)

	// Copy the buffer containing the line so far
	line := C.GoString(C.rl_line_buffer)

	// Generate suggestions
	var suggest []string
	suggest = minicli.Suggest(line)

	if len(suggest) == 0 {
		// No suggestions.. fall back on default behavior (filename completion)
		if FilenameCompleter == nil {
			return C.rl_completion_matches(text,
				(*C.rl_compentry_func_t)(C.rl_filename_completion_function))
		}

		suggest = FilenameCompleter(line)
		if len(suggest) == 0 {
			// no dice, use the builtin
			return C.rl_completion_matches(text,
				(*C.rl_compentry_func_t)(C.rl_filename_completion_function))
		}
	}
	vals := append([]string{lcp(suggest)}, suggest...)

	// Copy suggestions into char**
	ptr := C.malloc(C.size_t(len(vals)+1) * C.size_t(ptrSize))
	for i, v := range vals {
		element := (**C.char)(unsafe.Pointer(uintptr(ptr) + uintptr(i)*ptrSize))
		*element = C.CString(v)
	}
	element := (**C.char)(unsafe.Pointer(uintptr(ptr) + uintptr(len(vals))*ptrSize))
	*element = nil

	return (**C.char)(ptr)
}