aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-03-17 14:32:01 +0200
committerTulir Asokan <tulir@maunium.net>2018-03-17 14:32:01 +0200
commitba379a1b4a97ee7eb56bed726f1c4edd76f76bb8 (patch)
tree57f02a6d8a2ff8bf8151c6928e2918add017b7fd
parentdacc7fd6a310d3945bc61983ec218d083900a98d (diff)
Add basic username/id autocompletion
-rw-r--r--advanced-inputfield.go11
-rw-r--r--view-main.go39
2 files changed, 45 insertions, 5 deletions
diff --git a/advanced-inputfield.go b/advanced-inputfield.go
index 97fbfab..8b5b47a 100644
--- a/advanced-inputfield.go
+++ b/advanced-inputfield.go
@@ -79,7 +79,7 @@ type AdvancedInputField struct {
done func(tcell.Key)
// An optional function which is called when the user presses tab.
- tabComplete func(text string, cursorOffset int)
+ tabComplete func(text string, cursorOffset int) string
}
// NewAdvancedInputField returns a new input field.
@@ -205,7 +205,7 @@ func (field *AdvancedInputField) SetDoneFunc(handler func(key tcell.Key)) *Advan
return field
}
-func (field *AdvancedInputField) SetTabCompleteFunc(handler func(text string, cursorOffset int)) *AdvancedInputField {
+func (field *AdvancedInputField) SetTabCompleteFunc(handler func(text string, cursorOffset int) string) *AdvancedInputField {
field.tabComplete = handler
return field
}
@@ -429,7 +429,12 @@ func (field *AdvancedInputField) InputHandler() func(event *tcell.EventKey, setF
}
case tcell.KeyTab: // Tab-completion
if field.tabComplete != nil {
- field.tabComplete(field.text, field.cursorOffset)
+ oldWidth := runewidth.StringWidth(field.text)
+ field.text = field.tabComplete(field.text, field.cursorOffset)
+ newWidth := runewidth.StringWidth(field.text)
+ if oldWidth != newWidth {
+ field.cursorOffset += newWidth - oldWidth
+ }
}
case tcell.KeyEnter, tcell.KeyEscape: // We're done.
if field.done != nil {
diff --git a/view-main.go b/view-main.go
index 5a3a70c..219e603 100644
--- a/view-main.go
+++ b/view-main.go
@@ -17,10 +17,13 @@
package main
import (
+ "fmt"
"strings"
"time"
+ "unicode"
"github.com/gdamore/tcell"
+ "github.com/mattn/go-runewidth"
"maunium.net/go/gomatrix"
"maunium.net/go/tview"
)
@@ -96,11 +99,43 @@ func (view *MainView) InputChanged(text string) {
}
}
-func (view *MainView) InputTabComplete(text string, cursorOffset int) {
+func findWordToTabComplete(text string) string {
+ output := ""
+ runes := []rune(text)
+ for i := len(runes) - 1; i >= 0; i-- {
+ if unicode.IsSpace(runes[i]) {
+ break
+ }
+ output = string(runes[i]) + output
+ }
+ return output
+}
+
+func (view *RoomView) AutocompleteUser(existingText string) (completions []string) {
+ for _, user := range view.room.GetMembers() {
+ if strings.HasPrefix(user.DisplayName, existingText) {
+ completions = append(completions, user.DisplayName)
+ } else if strings.HasPrefix(user.UserID, existingText) {
+ completions = append(completions, user.UserID)
+ }
+ }
+ return
+}
+
+func (view *MainView) InputTabComplete(text string, cursorOffset int) string {
roomView, _ := view.rooms[view.CurrentRoomID()]
if roomView != nil {
- // text[0:cursorOffset]
+ str := runewidth.Truncate(text, cursorOffset, "")
+ word := findWordToTabComplete(str)
+ userCompletions := roomView.AutocompleteUser(word)
+ if len(userCompletions) == 1 {
+ text = str[0:len(str)-len(word)] + userCompletions[0] + text[len(str):]
+ } else if len(userCompletions) > 1 && len(userCompletions) < 6 {
+ roomView.status.Clear()
+ fmt.Fprintf(roomView.status, "Completions: %s", strings.Join(userCompletions, ", "))
+ }
}
+ return text
}
func (view *MainView) InputDone(key tcell.Key) {