mirror of
https://github.com/zyedidia/micro.git
synced 2025-06-18 23:05:40 -04:00
Merge 40f399730d
into 5eddf5b85d
This commit is contained in:
commit
e4b34b99f4
@ -906,27 +906,22 @@ func (h *BufPane) OutdentSelection() bool {
|
|||||||
// Autocomplete cycles the suggestions and performs autocompletion if there are suggestions
|
// Autocomplete cycles the suggestions and performs autocompletion if there are suggestions
|
||||||
func (h *BufPane) Autocomplete() bool {
|
func (h *BufPane) Autocomplete() bool {
|
||||||
b := h.Buf
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.HasSuggestions {
|
prevSuggestion := b.CycleAutocomplete(true)
|
||||||
b.CycleAutocomplete(true)
|
for i := 0; i < b.NumCursors(); i++ {
|
||||||
return true
|
if buffer.AutocompleteCursorCheck(b.GetCursor(i)) {
|
||||||
|
b.PerformSingleAutocomplete(prevSuggestion, b.GetCursor(i))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.Cursor.X == 0 {
|
return true
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.Autocomplete(buffer.BufferComplete)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CycleAutocompleteBack cycles back in the autocomplete suggestion list
|
// CycleAutocompleteBack cycles back in the autocomplete suggestion list
|
||||||
@ -935,8 +930,14 @@ func (h *BufPane) CycleAutocompleteBack() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.Buf.HasSuggestions {
|
b := h.Buf
|
||||||
h.Buf.CycleAutocomplete(false)
|
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 true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -191,30 +191,52 @@ func (h *InfoPane) HistorySearchDown() {
|
|||||||
// Autocomplete begins autocompletion
|
// Autocomplete begins autocompletion
|
||||||
func (h *InfoPane) CommandComplete() {
|
func (h *InfoPane) CommandComplete() {
|
||||||
b := h.Buf
|
b := h.Buf
|
||||||
if b.HasSuggestions {
|
c := b.GetActiveCursor()
|
||||||
b.CycleAutocomplete(true)
|
|
||||||
|
cc := buffer.AutocompleteCursorCheck(c)
|
||||||
|
rc := buffer.AutocompleteRuneCheck(c)
|
||||||
|
|
||||||
|
// Cycling commands
|
||||||
|
if !b.HasSuggestions && !cc && !rc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c := b.GetActiveCursor()
|
if b.HasSuggestions {
|
||||||
|
if !cc {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
prevSuggestion := b.CycleAutocomplete(true)
|
||||||
|
b.PerformSingleAutocomplete(prevSuggestion, c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise start autocomplete
|
||||||
l := b.LineBytes(0)
|
l := b.LineBytes(0)
|
||||||
l = util.SliceStart(l, c.X)
|
l = util.SliceStart(l, c.X)
|
||||||
|
|
||||||
args := bytes.Split(l, []byte{' '})
|
args := bytes.Split(l, []byte{' '})
|
||||||
cmd := string(args[0])
|
cmd := string(args[0])
|
||||||
|
|
||||||
|
var completer buffer.Completer = nil
|
||||||
|
|
||||||
if h.PromptType == "Command" {
|
if h.PromptType == "Command" {
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
b.Autocomplete(CommandComplete)
|
completer = CommandComplete
|
||||||
} else if action, ok := commands[cmd]; ok {
|
} else if action, ok := commands[cmd]; ok {
|
||||||
if action.completer != nil {
|
completer = action.completer
|
||||||
b.Autocomplete(action.completer)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// by default use filename autocompletion
|
// 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
|
// ExecuteCommand completes the prompt
|
||||||
|
@ -23,19 +23,37 @@ func (b *Buffer) GetSuggestions() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autocomplete starts the autocomplete process
|
func AutocompleteRuneCheck(cursor *Cursor) bool {
|
||||||
func (b *Buffer) Autocomplete(c Completer) 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)
|
b.Completions, b.Suggestions = c(b)
|
||||||
if len(b.Completions) != len(b.Suggestions) || len(b.Completions) == 0 {
|
if len(b.Completions) != len(b.Suggestions) || len(b.Completions) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
b.CurSuggestion = -1
|
b.CurSuggestion = -1
|
||||||
b.CycleAutocomplete(true)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// CycleAutocomplete moves to the next suggestion
|
// CycleAutocomplete moves to the next suggestion and return the previous suggestion
|
||||||
func (b *Buffer) CycleAutocomplete(forward bool) {
|
func (b *Buffer) CycleAutocomplete(forward bool) int {
|
||||||
prevSuggestion := b.CurSuggestion
|
prevSuggestion := b.CurSuggestion
|
||||||
|
|
||||||
if forward {
|
if forward {
|
||||||
@ -49,17 +67,25 @@ func (b *Buffer) CycleAutocomplete(forward bool) {
|
|||||||
b.CurSuggestion = len(b.Suggestions) - 1
|
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 {
|
if len(b.Suggestions) > 1 {
|
||||||
b.HasSuggestions = true
|
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
|
// GetWord gets the most recent word separated by any separator
|
||||||
|
Loading…
Reference in New Issue
Block a user