Skip to content

Commit c16ec82

Browse files
Merge branch 'MultiCursorAutoComplete' into dev
2 parents fd21425 + 5967646 commit c16ec82

File tree

4 files changed

+76
-35
lines changed

4 files changed

+76
-35
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
> - [Adding timeout when fetching plugin & more clear plugin error message #3389](https://github.com/zyedidia/micro/pull/3389)
1414
> - [Adding Jumping to opening and closing brace logic and actions #3384](https://github.com/zyedidia/micro/pull/3384)
1515
> - [Allowing plugin to add cursor in custom Loc #3441](https://github.com/zyedidia/micro/pull/3441)
16+
> - [Adding auto complete support for multi cursors #3442](https://github.com/zyedidia/micro/pull/3442)
1617
>
1718
> To see the diff between this and upstream master, click [here](https://github.com/zyedidia/micro/compare/master...Neko-Box-Coder:micro-dev:dev)
1819

internal/action/actions.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -845,25 +845,23 @@ func (h *BufPane) OutdentSelection() bool {
845845
func (h *BufPane) Autocomplete() bool {
846846
b := h.Buf
847847

848-
if h.Cursor.HasSelection() {
848+
// Don't autocomplete at all if the active cursor cannot be autocomplete
849+
if !buffer.AutocompleteCheck(h.Cursor) {
849850
return false
850851
}
851852

852-
if h.Cursor.X == 0 {
853-
return false
854-
}
855-
r := h.Cursor.RuneUnder(h.Cursor.X)
856-
prev := h.Cursor.RuneUnder(h.Cursor.X - 1)
857-
if !util.IsAutocomplete(prev) || util.IsWordChar(r) {
858-
// don't autocomplete if cursor is within a word
853+
if !b.HasSuggestions && !b.StartAutocomplete(buffer.BufferComplete) {
859854
return false
860855
}
861856

862-
if b.HasSuggestions {
863-
b.CycleAutocomplete(true)
864-
return true
857+
prevSuggestion := b.CycleAutocomplete(true)
858+
for i := 0; i < b.NumCursors(); i++ {
859+
if buffer.AutocompleteCheck(b.GetCursor(i)) {
860+
b.PerformSingleAutocomplete(prevSuggestion, b.GetCursor(i))
861+
}
865862
}
866-
return b.Autocomplete(buffer.BufferComplete)
863+
864+
return true
867865
}
868866

869867
// CycleAutocompleteBack cycles back in the autocomplete suggestion list
@@ -872,8 +870,14 @@ func (h *BufPane) CycleAutocompleteBack() bool {
872870
return false
873871
}
874872

875-
if h.Buf.HasSuggestions {
876-
h.Buf.CycleAutocomplete(false)
873+
b := h.Buf
874+
if b.HasSuggestions {
875+
prevSuggestion := b.CycleAutocomplete(false)
876+
for i := 0; i < b.NumCursors(); i++ {
877+
if buffer.AutocompleteCheck(b.GetCursor(i)) {
878+
b.PerformSingleAutocomplete(prevSuggestion, b.GetCursor(i))
879+
}
880+
}
877881
return true
878882
}
879883
return false

internal/action/infopane.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,30 +191,44 @@ func (h *InfoPane) HistorySearchDown() {
191191
// Autocomplete begins autocompletion
192192
func (h *InfoPane) CommandComplete() {
193193
b := h.Buf
194+
c := b.GetActiveCursor()
195+
196+
// Cycling commands
197+
if !buffer.AutocompleteCheck(c) {
198+
return
199+
}
194200
if b.HasSuggestions {
195-
b.CycleAutocomplete(true)
201+
prevSuggestion := b.CycleAutocomplete(true)
202+
b.PerformSingleAutocomplete(prevSuggestion, c)
196203
return
197204
}
198205

199-
c := b.GetActiveCursor()
206+
// Otherwise start autocomplete
200207
l := b.LineBytes(0)
201208
l = util.SliceStart(l, c.X)
202-
203209
args := bytes.Split(l, []byte{' '})
204210
cmd := string(args[0])
205211

212+
var completer buffer.Completer = nil
213+
206214
if h.PromptType == "Command" {
207215
if len(args) == 1 {
208-
b.Autocomplete(CommandComplete)
216+
completer = CommandComplete
209217
} else if action, ok := commands[cmd]; ok {
210-
if action.completer != nil {
211-
b.Autocomplete(action.completer)
212-
}
218+
completer = action.completer
213219
}
214220
} else {
215221
// by default use filename autocompletion
216-
b.Autocomplete(buffer.FileComplete)
222+
completer = buffer.FileComplete
223+
}
224+
if completer == nil {
225+
return
226+
}
227+
if !b.StartAutocomplete(completer) {
228+
return
217229
}
230+
prevSuggestion := b.CycleAutocomplete(true)
231+
b.PerformSingleAutocomplete(prevSuggestion, c)
218232
}
219233

220234
// ExecuteCommand completes the prompt

internal/buffer/autocomplete.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,33 @@ func (b *Buffer) GetSuggestions() {
2323

2424
}
2525

26-
// Autocomplete starts the autocomplete process
27-
func (b *Buffer) Autocomplete(c Completer) bool {
26+
func AutocompleteCheck(cursor *Cursor) bool {
27+
if cursor.HasSelection() {
28+
return false
29+
}
30+
if cursor.X == 0 {
31+
return false
32+
}
33+
r := cursor.RuneUnder(cursor.X)
34+
prev := cursor.RuneUnder(cursor.X - 1)
35+
if !util.IsAutocomplete(prev) || util.IsWordChar(r) {
36+
// don't autocomplete if cursor is within a word
37+
return false
38+
}
39+
return true
40+
}
41+
42+
func (b *Buffer) StartAutocomplete(c Completer) bool {
2843
b.Completions, b.Suggestions = c(b)
2944
if len(b.Completions) != len(b.Suggestions) || len(b.Completions) == 0 {
3045
return false
3146
}
3247
b.CurSuggestion = -1
33-
b.CycleAutocomplete(true)
3448
return true
3549
}
3650

37-
// CycleAutocomplete moves to the next suggestion
38-
func (b *Buffer) CycleAutocomplete(forward bool) {
51+
// CycleAutocomplete moves to the next suggestion and return the previous suggestion
52+
func (b *Buffer) CycleAutocomplete(forward bool) int {
3953
prevSuggestion := b.CurSuggestion
4054

4155
if forward {
@@ -49,17 +63,25 @@ func (b *Buffer) CycleAutocomplete(forward bool) {
4963
b.CurSuggestion = len(b.Suggestions) - 1
5064
}
5165

52-
c := b.GetActiveCursor()
53-
start := c.Loc
54-
end := c.Loc
55-
if prevSuggestion < len(b.Suggestions) && prevSuggestion >= 0 {
56-
start = end.Move(-util.CharacterCountInString(b.Completions[prevSuggestion]), b)
57-
}
58-
59-
b.Replace(start, end, b.Completions[b.CurSuggestion])
6066
if len(b.Suggestions) > 1 {
6167
b.HasSuggestions = true
6268
}
69+
70+
return prevSuggestion
71+
}
72+
73+
func (b *Buffer) PerformSingleAutocomplete(prevSuggestion int, cursor *Cursor) {
74+
curLoc := cursor.Loc
75+
curStart := curLoc
76+
curEnd := curLoc
77+
78+
if prevSuggestion < len(b.Suggestions) && prevSuggestion >= 0 {
79+
curStart = curEnd.Move(-util.CharacterCountInString(b.Completions[prevSuggestion]), b)
80+
}
81+
82+
hasSuggestions := b.HasSuggestions
83+
b.Replace(curStart, curEnd, b.Completions[b.CurSuggestion])
84+
b.HasSuggestions = hasSuggestions
6385
}
6486

6587
// GetWord gets the most recent word separated by any separator

0 commit comments

Comments
 (0)