Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions internal/action/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -906,27 +906,22 @@ func (h *BufPane) OutdentSelection() bool {
// Autocomplete cycles the suggestions and performs autocompletion if there are suggestions
func (h *BufPane) Autocomplete() bool {
b := h.Buf
cc := buffer.AutocompleteCursorCheck(h.Cursor)
rc := buffer.AutocompleteRuneCheck(h.Cursor)

if h.Cursor.HasSelection() {
// Don't autocomplete at all if the active cursor cannot be autocomplete
if !b.HasSuggestions && (!rc || !cc || !b.StartAutocomplete(buffer.BufferComplete)) {
return false
}

if b.HasSuggestions {
b.CycleAutocomplete(true)
return true
}

if h.Cursor.X == 0 {
return false
}
r := h.Cursor.RuneUnder(h.Cursor.X)
prev := h.Cursor.RuneUnder(h.Cursor.X - 1)
if !util.IsAutocomplete(prev) || util.IsWordChar(r) {
// don't autocomplete if cursor is within a word
return false
prevSuggestion := b.CycleAutocomplete(true)
for i := 0; i < b.NumCursors(); i++ {
if buffer.AutocompleteCursorCheck(b.GetCursor(i)) {
b.PerformSingleAutocomplete(prevSuggestion, b.GetCursor(i))
}
}

return b.Autocomplete(buffer.BufferComplete)
return true
}

// CycleAutocompleteBack cycles back in the autocomplete suggestion list
Expand All @@ -935,8 +930,14 @@ func (h *BufPane) CycleAutocompleteBack() bool {
return false
}

if h.Buf.HasSuggestions {
h.Buf.CycleAutocomplete(false)
b := h.Buf
if b.HasSuggestions {
prevSuggestion := b.CycleAutocomplete(false)
for i := 0; i < b.NumCursors(); i++ {
if buffer.AutocompleteCursorCheck(b.GetCursor(i)) {
b.PerformSingleAutocomplete(prevSuggestion, b.GetCursor(i))
}
}
return true
}
return false
Expand Down
38 changes: 30 additions & 8 deletions internal/action/infopane.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,30 +191,52 @@ func (h *InfoPane) HistorySearchDown() {
// Autocomplete begins autocompletion
func (h *InfoPane) CommandComplete() {
b := h.Buf
c := b.GetActiveCursor()

cc := buffer.AutocompleteCursorCheck(c)
rc := buffer.AutocompleteRuneCheck(c)

// Cycling commands
if !b.HasSuggestions && !cc && !rc {
return
}

if b.HasSuggestions {
b.CycleAutocomplete(true)
if !cc {
return
}

prevSuggestion := b.CycleAutocomplete(true)
b.PerformSingleAutocomplete(prevSuggestion, c)
return
}

c := b.GetActiveCursor()
// Otherwise start autocomplete
l := b.LineBytes(0)
l = util.SliceStart(l, c.X)

args := bytes.Split(l, []byte{' '})
cmd := string(args[0])

var completer buffer.Completer = nil

if h.PromptType == "Command" {
if len(args) == 1 {
b.Autocomplete(CommandComplete)
completer = CommandComplete
} else if action, ok := commands[cmd]; ok {
if action.completer != nil {
b.Autocomplete(action.completer)
}
completer = action.completer
}
} else {
// by default use filename autocompletion
b.Autocomplete(buffer.FileComplete)
completer = buffer.FileComplete
}
if completer == nil {
return
}
if !b.StartAutocomplete(completer) {
return
}
prevSuggestion := b.CycleAutocomplete(true)
b.PerformSingleAutocomplete(prevSuggestion, c)
}

// ExecuteCommand completes the prompt
Expand Down
52 changes: 39 additions & 13 deletions internal/buffer/autocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,37 @@ func (b *Buffer) GetSuggestions() {

}

// Autocomplete starts the autocomplete process
func (b *Buffer) Autocomplete(c Completer) bool {
func AutocompleteRuneCheck(cursor *Cursor) bool {
r := cursor.RuneUnder(cursor.X)
prev := cursor.RuneUnder(cursor.X - 1)
if !util.IsAutocomplete(prev) || util.IsWordChar(r) {
// don't autocomplete if cursor is within a word
return false
}
return true
}

func AutocompleteCursorCheck(cursor *Cursor) bool {
if cursor.HasSelection() {
return false
}
if cursor.X == 0 {
return false
}
return true
}

func (b *Buffer) StartAutocomplete(c Completer) bool {
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)
return true
}

// CycleAutocomplete moves to the next suggestion
func (b *Buffer) CycleAutocomplete(forward bool) {
// CycleAutocomplete moves to the next suggestion and return the previous suggestion
func (b *Buffer) CycleAutocomplete(forward bool) int {
prevSuggestion := b.CurSuggestion

if forward {
Expand All @@ -49,17 +67,25 @@ func (b *Buffer) CycleAutocomplete(forward bool) {
b.CurSuggestion = len(b.Suggestions) - 1
}

c := b.GetActiveCursor()
start := c.Loc
end := c.Loc
if prevSuggestion < len(b.Suggestions) && prevSuggestion >= 0 {
start = end.Move(-util.CharacterCountInString(b.Completions[prevSuggestion]), b)
}

b.Replace(start, end, b.Completions[b.CurSuggestion])
if len(b.Suggestions) > 1 {
b.HasSuggestions = true
}

return prevSuggestion
}

func (b *Buffer) PerformSingleAutocomplete(prevSuggestion int, cursor *Cursor) {
curLoc := cursor.Loc
curStart := curLoc
curEnd := curLoc

if prevSuggestion < len(b.Suggestions) && prevSuggestion >= 0 {
curStart = curEnd.Move(-util.CharacterCountInString(b.Completions[prevSuggestion]), b)
}

hasSuggestions := b.HasSuggestions
b.Replace(curStart, curEnd, b.Completions[b.CurSuggestion])
b.HasSuggestions = hasSuggestions
}

// GetWord gets the most recent word separated by any separator
Expand Down