diff --git a/internal/action/actions.go b/internal/action/actions.go index ebd5189986..ce1d0e1099 100644 --- a/internal/action/actions.go +++ b/internal/action/actions.go @@ -903,6 +903,20 @@ func (h *BufPane) OutdentSelection() bool { return false } +func canAutocomplete(c *buffer.Cursor) bool { + if c.X == 0 { + return false + } + + r := c.RuneUnder(c.X) + prev := c.RuneUnder(c.X - 1) + if !util.IsAutocomplete(prev) || util.IsWordChar(r) { + // don't autocomplete if cursor is within a word + return false + } + return true +} + // Autocomplete cycles the suggestions and performs autocompletion if there are suggestions func (h *BufPane) Autocomplete() bool { b := h.Buf @@ -916,7 +930,7 @@ func (h *BufPane) Autocomplete() bool { return true } - return b.Autocomplete(buffer.BufferComplete) + return b.AutocompleteCB(buffer.BufferComplete, canAutocomplete) } // CycleAutocompleteBack cycles back in the autocomplete suggestion list @@ -926,7 +940,7 @@ func (h *BufPane) CycleAutocompleteBack() bool { } if h.Buf.HasSuggestions { - h.Buf.CycleAutocomplete(false) + h.Buf.CycleAutocompleteCB(false, canAutocomplete) return true } return false diff --git a/internal/buffer/autocomplete.go b/internal/buffer/autocomplete.go index d08325577e..be4b4e5890 100644 --- a/internal/buffer/autocomplete.go +++ b/internal/buffer/autocomplete.go @@ -25,20 +25,29 @@ func (b *Buffer) GetSuggestions() { // Autocomplete starts the autocomplete process func (b *Buffer) Autocomplete(c Completer) bool { - if !b.GetActiveCursor().CanAutocomplete() { + return b.AutocompleteCB(c, nil) +} + +func (b *Buffer) AutocompleteCB(c Completer, checkCB func(*Cursor) bool) bool { + if checkCB != nil && !checkCB(b.GetActiveCursor()) { return false } b.Completions, b.Suggestions = c(b) + if len(b.Completions) != len(b.Suggestions) || len(b.Completions) == 0 { return false } b.CurSuggestion = -1 - b.CycleAutocomplete(true) + b.CycleAutocompleteCB(true, checkCB) return true } // CycleAutocomplete moves to the next suggestion func (b *Buffer) CycleAutocomplete(forward bool) { + b.CycleAutocompleteCB(forward, nil) +} + +func (b *Buffer) CycleAutocompleteCB(forward bool, checkCB func(*Cursor) bool) { prevSuggestion := b.CurSuggestion if forward { @@ -56,7 +65,7 @@ func (b *Buffer) CycleAutocomplete(forward bool) { activeWord := make([]byte, len(tmpWord)) copy(activeWord, tmpWord) for _, c := range b.cursors { - if !c.CanAutocomplete() { + if checkCB != nil && !checkCB(c) { continue } @@ -85,20 +94,6 @@ func (c *Cursor) autocomplete(prevSuggestion int) { b.Replace(start, end, b.Completions[b.CurSuggestion]) } -func (c *Cursor) CanAutocomplete() bool { - if c.X == 0 { - return false - } - - r := c.RuneUnder(c.X) - prev := c.RuneUnder(c.X - 1) - if !util.IsAutocomplete(prev) || util.IsWordChar(r) { - // don't autocomplete if cursor is within a word - return false - } - return true -} - // GetWord gets the most recent word separated by any separator // (whitespace, punctuation, any non alphanumeric character) func (c *Cursor) GetWord() ([]byte, int) {