Example #1
0
func update_candidates(serial int, input string, providersp unsafe.Pointer, info map[string]interface{}) {
	texts := make(map[string]bool)
	providers := make(map[string][]string)
	descriptions := make(map[string][]string)
	distances := make(map[string]int)
	var lock sync.Mutex

	// from GlobalVocabulary
	l := GlobalVocabulary.Len()
	var word *Word
	for i := 0; i < l; i++ {
		word = GlobalVocabulary.GetByIndex(i)
		if match, distance := fuzzyMatch(word.Text, input); match {
			texts[word.Text] = true
			distances[word.Text] = distance
			providers[word.Text] = []string{}
		}
	}

	// get buffer content
	buffer := (*C.GtkTextBuffer)(info["buffer"].(unsafe.Pointer))
	var start_iter, end_iter C.GtkTextIter
	C.gtk_text_buffer_get_start_iter(buffer, &start_iter)
	C.gtk_text_buffer_get_end_iter(buffer, &end_iter)
	cContent := C.gtk_text_buffer_get_text(buffer, &start_iter, &end_iter, C.gtk_false())
	content := C.GoBytes(unsafe.Pointer(cContent), C.int(C.strlen((*C.char)(cContent))))

	result := sort(input, texts, distances, providers, descriptions)

	// extra providers
	for source, provider := range (*Providers)(providersp).Providers {
		go func() {
			lock.Lock()
			for _, pair := range provider(input, content, info) {
				text := pair[0]
				if input != "" {
					if match, _ := fuzzyMatch(text, input); !match {
						continue
					}
				}
				GlobalVocabulary.Add(text)
				texts[text] = true
				providers[text] = append(providers[text], source)
				descriptions[text] = append(descriptions[text], "<"+source+"> "+pair[1])
				distances[text] = 0
			}
			result := sort(input, texts, distances, providers, descriptions)
			lock.Unlock()
			C.emit()
			results <- Result{serial, result}
		}()
	}

	updateStore(result)

}
Example #2
0
func collect_words(bufferp unsafe.Pointer, isEditMode bool, rep unsafe.Pointer) {
	var start_iter, end_iter C.GtkTextIter
	buf := (*C.GtkTextBuffer)(bufferp)
	C.gtk_text_buffer_get_start_iter(buf, &start_iter)
	C.gtk_text_buffer_get_end_iter(buf, &end_iter)
	text := []byte(C.GoString((*C.char)(C.gtk_text_buffer_get_text(buf, &start_iter, &end_iter, C.gtk_false()))))
	C.gtk_text_buffer_get_iter_at_mark(buf, &start_iter, C.gtk_text_buffer_get_insert(buf))
	cursor_char_offset := int(C.gtk_text_iter_get_offset(&start_iter))
	go func() {
		byte_offset := 0
		char_offset := 0
		re := (*regexp.Regexp)(rep)
		decode_byte_offset := 0
		var word_start_char_offset, word_end_char_offset int
		var size int
		for {
			// find next word
			loc := re.FindIndex(text[byte_offset:])
			if loc == nil {
				return
			}
			// convert byte offset to char offset
			byte_offset += loc[0]
			for decode_byte_offset < byte_offset {
				_, size = utf8.DecodeRune(text[decode_byte_offset:])
				decode_byte_offset += size
				char_offset += 1
			}
			word_start_char_offset = char_offset
			byte_offset += loc[1] - loc[0]
			for decode_byte_offset < byte_offset {
				_, size = utf8.DecodeRune(text[decode_byte_offset:])
				decode_byte_offset += size
				char_offset += 1
			}
			word_end_char_offset = char_offset
			// skip current word in edit mode
			if isEditMode {
				if cursor_char_offset >= word_start_char_offset && cursor_char_offset <= word_end_char_offset {
					continue
				}
			}
			// add to global vocabulary
			GlobalVocabulary.Add(string(text[byte_offset-(loc[1]-loc[0]) : byte_offset]))
		}
	}()
}
Example #3
0
func set_relative_indicators(bufp unsafe.Pointer, viewp unsafe.Pointer, offsets []int, indicators []unsafe.Pointer) {
	buf := (*C.GtkTextBuffer)(bufp)
	view := (*C.GtkTextView)(viewp)
	var it C.GtkTextIter
	C.gtk_text_buffer_get_start_iter(buf, &it)
	var location C.GdkRectangle
	var left, top C.gint
	var indicator *C.GtkWidget
	for i, offset := range offsets {
		C.gtk_text_iter_set_offset(&it, C.gint(offset))
		C.gtk_text_view_get_iter_location(view, &it, &location)
		C.gtk_text_view_buffer_to_window_coords(view, C.GTK_TEXT_WINDOW_WIDGET, C.gint(location.x), C.gint(location.y), &left, &top)
		indicator = (*C.GtkWidget)(indicators[i])
		top += 8
		if left >= C.gint(0) && top >= C.gint(0) {
			C.gtk_widget_set_margin_start(indicator, left)
			C.gtk_widget_set_margin_top(indicator, top)
			C.gtk_widget_show(indicator)
		}
	}
}