@@ -25,6 +25,9 @@ func (b *Buffer) GetSuggestions() {
2525
2626// Autocomplete starts the autocomplete process
2727func (b * Buffer ) Autocomplete (c Completer ) bool {
28+ if ! b .GetActiveCursor ().CanAutocomplete () {
29+ return false
30+ }
2831 b .Completions , b .Suggestions = c (b )
2932 if len (b .Completions ) != len (b .Suggestions ) || len (b .Completions ) == 0 {
3033 return false
@@ -49,23 +52,57 @@ func (b *Buffer) CycleAutocomplete(forward bool) {
4952 b .CurSuggestion = len (b .Suggestions ) - 1
5053 }
5154
52- c := b .GetActiveCursor ()
55+ // cycle autocomplete for all except active cursors
56+ for i , c := range b .cursors {
57+ if i == b .curCursor || ! c .CanAutocomplete () {
58+ continue
59+ }
60+
61+ activeWord , _ := b .GetWordCursor (b .GetActiveCursor ())
62+ word , _ := b .GetWordCursor (c );
63+ if ! bytes .Equal (word , activeWord ) {
64+ continue
65+ }
66+
67+ b .AutocompleteSingle (c , prevSuggestion )
68+ }
69+
70+ // cycle autocomplete for active cursor
71+ b .AutocompleteSingle (b .GetActiveCursor (), prevSuggestion )
72+
73+ if len (b .Suggestions ) > 1 {
74+ b .HasSuggestions = true
75+ }
76+ }
77+
78+ func (b * Buffer ) AutocompleteSingle (c * Cursor , prevSuggestion int ) {
5379 start := c .Loc
5480 end := c .Loc
81+
5582 if prevSuggestion < len (b .Suggestions ) && prevSuggestion >= 0 {
5683 start = end .Move (- util .CharacterCountInString (b .Completions [prevSuggestion ]), b )
5784 }
5885
5986 b .Replace (start , end , b .Completions [b .CurSuggestion ])
60- if len (b .Suggestions ) > 1 {
61- b .HasSuggestions = true
87+ }
88+
89+ func (c * Cursor ) CanAutocomplete () bool {
90+ if c .X == 0 {
91+ return false
6292 }
93+
94+ r := c .RuneUnder (c .X )
95+ prev := c .RuneUnder (c .X - 1 )
96+ if ! util .IsAutocomplete (prev ) || util .IsWordChar (r ) {
97+ // don't autocomplete if cursor is within a word
98+ return false
99+ }
100+ return true
63101}
64102
65- // GetWord gets the most recent word separated by any separator
103+ // GetWordCursor gets the most recent word separated by any separator
66104// (whitespace, punctuation, any non alphanumeric character)
67- func (b * Buffer ) GetWord () ([]byte , int ) {
68- c := b .GetActiveCursor ()
105+ func (b * Buffer ) GetWordCursor (c * Cursor ) ([]byte , int ) {
69106 l := b .LineBytes (c .Y )
70107 l = util .SliceStart (l , c .X )
71108
@@ -82,6 +119,10 @@ func (b *Buffer) GetWord() ([]byte, int) {
82119 return input , c .X - util .CharacterCount (input )
83120}
84121
122+ func (b * Buffer ) GetWord () ([]byte , int ) {
123+ return b .GetWordCursor (b .GetActiveCursor ())
124+ }
125+
85126// GetArg gets the most recent word (separated by ' ' only)
86127func (b * Buffer ) GetArg () (string , int ) {
87128 c := b .GetActiveCursor ()
@@ -153,7 +194,7 @@ func FileComplete(b *Buffer) ([]string, []string) {
153194// BufferComplete autocompletes based on previous words in the buffer
154195func BufferComplete (b * Buffer ) ([]string , []string ) {
155196 c := b .GetActiveCursor ()
156- input , argstart := b .GetWord ( )
197+ input , argstart := b .GetWordCursor ( c )
157198
158199 if argstart == - 1 {
159200 return []string {}, []string {}
0 commit comments