From 4951f155ea27b19325b0805da2bfe9c97a51ee82 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Wed, 25 Dec 2019 12:54:51 -0500 Subject: [PATCH] Support for more complex action chaining --- internal/action/actions.go | 173 +++++++++++++++++++++---------- internal/action/bindings.go | 4 +- internal/action/bufpane.go | 197 ++++++++++++++++++++---------------- 3 files changed, 231 insertions(+), 143 deletions(-) diff --git a/internal/action/actions.go b/internal/action/actions.go index c8cd6b5d..585646a3 100644 --- a/internal/action/actions.go +++ b/internal/action/actions.go @@ -92,19 +92,19 @@ func (h *BufPane) MousePress(e *tcell.EventMouse) bool { h.Cursor.StoreVisualX() h.lastLoc = mouseLoc - return false + return true } // ScrollUpAction scrolls the view up func (h *BufPane) ScrollUpAction() bool { h.ScrollUp(util.IntOpt(h.Buf.Settings["scrollspeed"])) - return false + return true } // ScrollDownAction scrolls the view up func (h *BufPane) ScrollDownAction() bool { h.ScrollDown(util.IntOpt(h.Buf.Settings["scrollspeed"])) - return false + return true } // Center centers the view on the cursor @@ -118,6 +118,7 @@ func (h *BufPane) Center() bool { v.StartLine = 0 } h.SetView(v) + h.Relocate() return true } @@ -125,6 +126,7 @@ func (h *BufPane) Center() bool { func (h *BufPane) CursorUp() bool { h.Cursor.Deselect(true) h.Cursor.Up() + h.Relocate() return true } @@ -132,6 +134,7 @@ func (h *BufPane) CursorUp() bool { func (h *BufPane) CursorDown() bool { h.Cursor.Deselect(true) h.Cursor.Down() + h.Relocate() return true } @@ -156,6 +159,7 @@ func (h *BufPane) CursorLeft() bool { h.Cursor.Left() } } + h.Relocate() return true } @@ -182,6 +186,7 @@ func (h *BufPane) CursorRight() bool { } } + h.Relocate() return true } @@ -189,6 +194,7 @@ func (h *BufPane) CursorRight() bool { func (h *BufPane) WordRight() bool { h.Cursor.Deselect(false) h.Cursor.WordRight() + h.Relocate() return true } @@ -196,6 +202,7 @@ func (h *BufPane) WordRight() bool { func (h *BufPane) WordLeft() bool { h.Cursor.Deselect(true) h.Cursor.WordLeft() + h.Relocate() return true } @@ -206,6 +213,7 @@ func (h *BufPane) SelectUp() bool { } h.Cursor.Up() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -216,6 +224,7 @@ func (h *BufPane) SelectDown() bool { } h.Cursor.Down() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -231,6 +240,7 @@ func (h *BufPane) SelectLeft() bool { } h.Cursor.Left() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -246,6 +256,7 @@ func (h *BufPane) SelectRight() bool { } h.Cursor.Right() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -256,6 +267,7 @@ func (h *BufPane) SelectWordRight() bool { } h.Cursor.WordRight() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -266,6 +278,7 @@ func (h *BufPane) SelectWordLeft() bool { } h.Cursor.WordLeft() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -278,6 +291,7 @@ func (h *BufPane) StartOfLine() bool { // } else { // h.Cursor.StartOfText() // } + h.Relocate() return true } @@ -285,12 +299,14 @@ func (h *BufPane) StartOfLine() bool { func (h *BufPane) EndOfLine() bool { h.Cursor.Deselect(true) h.Cursor.End() + h.Relocate() return true } // SelectLine selects the entire current line func (h *BufPane) SelectLine() bool { h.Cursor.SelectLine() + h.Relocate() return true } @@ -301,6 +317,7 @@ func (h *BufPane) SelectToStartOfLine() bool { } h.Cursor.Start() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -311,6 +328,7 @@ func (h *BufPane) SelectToEndOfLine() bool { } h.Cursor.End() h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -328,6 +346,7 @@ func (h *BufPane) ParagraphPrevious() bool { if line == 0 { h.Cursor.Loc = h.Buf.Start() } + h.Relocate() return true } @@ -345,6 +364,7 @@ func (h *BufPane) ParagraphNext() bool { if line == h.Buf.LinesNum() { h.Cursor.Loc = h.Buf.End() } + h.Relocate() return true } @@ -352,6 +372,7 @@ func (h *BufPane) ParagraphNext() bool { // on the user's settings func (h *BufPane) Retab() bool { h.Buf.Retab() + h.Relocate() return true } @@ -360,6 +381,7 @@ func (h *BufPane) CursorStart() bool { h.Cursor.Deselect(true) h.Cursor.X = 0 h.Cursor.Y = 0 + h.Relocate() return true } @@ -368,6 +390,7 @@ func (h *BufPane) CursorEnd() bool { h.Cursor.Deselect(true) h.Cursor.Loc = h.Buf.End() h.Cursor.StoreVisualX() + h.Relocate() return true } @@ -378,6 +401,7 @@ func (h *BufPane) SelectToStart() bool { } h.CursorStart() h.Cursor.SelectTo(h.Buf.Start()) + h.Relocate() return true } @@ -388,6 +412,7 @@ func (h *BufPane) SelectToEnd() bool { } h.CursorEnd() h.Cursor.SelectTo(h.Buf.End()) + h.Relocate() return true } @@ -420,6 +445,7 @@ func (h *BufPane) InsertNewline() bool { } } h.Cursor.LastVisualX = h.Cursor.GetVisualX() + h.Relocate() return true } @@ -449,6 +475,7 @@ func (h *BufPane) Backspace() bool { } } h.Cursor.LastVisualX = h.Cursor.GetVisualX() + h.Relocate() return true } @@ -459,6 +486,7 @@ func (h *BufPane) DeleteWordRight() bool { h.Cursor.DeleteSelection() h.Cursor.ResetSelection() } + h.Relocate() return true } @@ -469,6 +497,7 @@ func (h *BufPane) DeleteWordLeft() bool { h.Cursor.DeleteSelection() h.Cursor.ResetSelection() } + h.Relocate() return true } @@ -483,6 +512,7 @@ func (h *BufPane) Delete() bool { h.Buf.Remove(loc, loc.Move(1, h.Buf)) } } + h.Relocate() return true } @@ -513,6 +543,7 @@ func (h *BufPane) IndentSelection() bool { } h.Buf.RelocateCursors() + h.Relocate() return true } return false @@ -531,6 +562,7 @@ func (h *BufPane) OutdentLine() bool { h.Buf.Remove(buffer.Loc{X: 0, Y: h.Cursor.Y}, buffer.Loc{X: 1, Y: h.Cursor.Y}) } h.Buf.RelocateCursors() + h.Relocate() return true } @@ -557,29 +589,37 @@ func (h *BufPane) OutdentSelection() bool { } h.Buf.RelocateCursors() + h.Relocate() return true } return false } -// InsertTab inserts a tab or spaces -func (h *BufPane) InsertTab() bool { +// Autocomplete cycles the suggestions and performs autocompletion if there are suggestions +func (h *BufPane) Autocomplete() bool { b := h.Buf + + if h.Cursor.HasSelection() { + return false + } + if b.HasSuggestions { b.CycleAutocomplete(true) return true } + return b.Autocomplete(buffer.BufferComplete) +} +// InsertTab inserts a tab or spaces +func (h *BufPane) InsertTab() bool { + b := h.Buf l := b.LineBytes(h.Cursor.Y) l = util.SliceStart(l, h.Cursor.X) - hasComplete := b.Autocomplete(buffer.BufferComplete) - if !hasComplete { - indent := b.IndentString(util.IntOpt(b.Settings["tabsize"])) - tabBytes := len(indent) - bytesUntilIndent := tabBytes - (h.Cursor.GetVisualX() % tabBytes) - b.Insert(h.Cursor.Loc, indent[:bytesUntilIndent]) - return true - } + indent := b.IndentString(util.IntOpt(b.Settings["tabsize"])) + tabBytes := len(indent) + bytesUntilIndent := tabBytes - (h.Cursor.GetVisualX() % tabBytes) + b.Insert(h.Cursor.Loc, indent[:bytesUntilIndent]) + h.Relocate() return true } @@ -588,7 +628,7 @@ func (h *BufPane) SaveAll() bool { for _, b := range buffer.OpenBuffers { b.Save() } - return false + return true } // Save the buffer to disk @@ -600,7 +640,7 @@ func (h *BufPane) Save() bool { h.saveBufToFile(h.Buf.Path) } - return false + return true } // SaveAs saves the buffer to disk with the given name @@ -618,7 +658,7 @@ func (h *BufPane) SaveAs() bool { } }) - return false + return true } // This function saves the buffer to `filename` and changes the buffer's path and name @@ -690,7 +730,7 @@ func (h *BufPane) Find() bool { h.Relocate() }) - return false + return true } // FindNext searches forwards for the last used search term @@ -716,6 +756,7 @@ func (h *BufPane) FindNext() bool { } else { h.Cursor.ResetSelection() } + h.Relocate() return true } @@ -742,6 +783,7 @@ func (h *BufPane) FindPrevious() bool { } else { h.Cursor.ResetSelection() } + h.Relocate() return true } @@ -749,6 +791,7 @@ func (h *BufPane) FindPrevious() bool { func (h *BufPane) Undo() bool { h.Buf.Undo() InfoBar.Message("Undid action") + h.Relocate() return true } @@ -756,6 +799,7 @@ func (h *BufPane) Undo() bool { func (h *BufPane) Redo() bool { h.Buf.Redo() InfoBar.Message("Redid action") + h.Relocate() return true } @@ -766,6 +810,7 @@ func (h *BufPane) Copy() bool { h.freshClip = true InfoBar.Message("Copied selection") } + h.Relocate() return true } @@ -791,6 +836,7 @@ func (h *BufPane) CutLine() bool { h.Cursor.DeleteSelection() h.Cursor.ResetSelection() InfoBar.Message("Cut line") + h.Relocate() return true } @@ -803,6 +849,7 @@ func (h *BufPane) Cut() bool { h.freshClip = true InfoBar.Message("Cut selection") + h.Relocate() return true } else { return h.CutLine() @@ -820,6 +867,7 @@ func (h *BufPane) DuplicateLine() bool { } InfoBar.Message("Duplicated line") + h.Relocate() return true } @@ -832,6 +880,7 @@ func (h *BufPane) DeleteLine() bool { h.Cursor.DeleteSelection() h.Cursor.ResetSelection() InfoBar.Message("Deleted line") + h.Relocate() return true } @@ -839,8 +888,8 @@ func (h *BufPane) DeleteLine() bool { func (h *BufPane) MoveLinesUp() bool { if h.Cursor.HasSelection() { if h.Cursor.CurSelection[0].Y == 0 { - InfoBar.Message("Can not move further up") - return true + InfoBar.Message("Cannot move further up") + return false } start := h.Cursor.CurSelection[0].Y end := h.Cursor.CurSelection[1].Y @@ -855,8 +904,8 @@ func (h *BufPane) MoveLinesUp() bool { h.Cursor.CurSelection[1].Y -= 1 } else { if h.Cursor.Loc.Y == 0 { - InfoBar.Message("Can not move further up") - return true + InfoBar.Message("Cannot move further up") + return false } h.Buf.MoveLinesUp( h.Cursor.Loc.Y, @@ -864,6 +913,7 @@ func (h *BufPane) MoveLinesUp() bool { ) } + h.Relocate() return true } @@ -871,8 +921,8 @@ func (h *BufPane) MoveLinesUp() bool { func (h *BufPane) MoveLinesDown() bool { if h.Cursor.HasSelection() { if h.Cursor.CurSelection[1].Y >= h.Buf.LinesNum() { - InfoBar.Message("Can not move further down") - return true + InfoBar.Message("Cannot move further down") + return false } start := h.Cursor.CurSelection[0].Y end := h.Cursor.CurSelection[1].Y @@ -886,8 +936,8 @@ func (h *BufPane) MoveLinesDown() bool { ) } else { if h.Cursor.Loc.Y >= h.Buf.LinesNum()-1 { - InfoBar.Message("Can not move further down") - return true + InfoBar.Message("Cannot move further down") + return false } h.Buf.MoveLinesDown( h.Cursor.Loc.Y, @@ -895,6 +945,7 @@ func (h *BufPane) MoveLinesDown() bool { ) } + h.Relocate() return true } @@ -903,6 +954,7 @@ func (h *BufPane) MoveLinesDown() bool { func (h *BufPane) Paste() bool { clip, _ := clipboard.ReadAll("clipboard") h.paste(clip) + h.Relocate() return true } @@ -910,6 +962,7 @@ func (h *BufPane) Paste() bool { func (h *BufPane) PastePrimary() bool { clip, _ := clipboard.ReadAll("primary") h.paste(clip) + h.Relocate() return true } @@ -948,6 +1001,7 @@ func (h *BufPane) JumpToMatchingBrace() bool { } } + h.Relocate() return true } @@ -958,6 +1012,7 @@ func (h *BufPane) SelectAll() bool { // Put the cursor at the beginning h.Cursor.X = 0 h.Cursor.Y = 0 + h.Relocate() return true } @@ -968,7 +1023,7 @@ func (h *BufPane) OpenFile() bool { h.HandleCommand(resp) } }) - return false + return true } // Start moves the viewport to the start of the buffer @@ -976,7 +1031,7 @@ func (h *BufPane) Start() bool { v := h.GetView() v.StartLine = 0 h.SetView(v) - return false + return true } // End moves the viewport to the end of the buffer @@ -990,7 +1045,7 @@ func (h *BufPane) End() bool { v.StartLine = h.Buf.LinesNum() - v.Height h.SetView(v) } - return false + return true } // PageUp scrolls the view up a page @@ -1002,7 +1057,7 @@ func (h *BufPane) PageUp() bool { v.StartLine = 0 } h.SetView(v) - return false + return true } // PageDown scrolls the view down a page @@ -1013,7 +1068,7 @@ func (h *BufPane) PageDown() bool { } else if h.Buf.LinesNum() >= v.Height { v.StartLine = h.Buf.LinesNum() - v.Height } - return false + return true } // SelectPageUp selects up one page @@ -1023,6 +1078,7 @@ func (h *BufPane) SelectPageUp() bool { } h.Cursor.UpN(h.GetView().Height) h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -1033,6 +1089,7 @@ func (h *BufPane) SelectPageDown() bool { } h.Cursor.DownN(h.GetView().Height) h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() return true } @@ -1046,6 +1103,7 @@ func (h *BufPane) CursorPageUp() bool { h.Cursor.StoreVisualX() } h.Cursor.UpN(h.GetView().Height) + h.Relocate() return true } @@ -1059,6 +1117,7 @@ func (h *BufPane) CursorPageDown() bool { h.Cursor.StoreVisualX() } h.Cursor.DownN(h.GetView().Height) + h.Relocate() return true } @@ -1071,7 +1130,7 @@ func (h *BufPane) HalfPageUp() bool { v.StartLine = 0 } h.SetView(v) - return false + return true } // HalfPageDown scrolls the view down half a page @@ -1085,7 +1144,7 @@ func (h *BufPane) HalfPageDown() bool { } } h.SetView(v) - return false + return true } // ToggleRuler turns line numbers off and on @@ -1097,13 +1156,13 @@ func (h *BufPane) ToggleRuler() bool { h.Buf.Settings["ruler"] = false InfoBar.Message("Disabled ruler") } - return false + return true } // ClearStatus clears the messenger bar func (h *BufPane) ClearStatus() bool { InfoBar.Message("") - return false + return true } // ToggleHelp toggles the help screen @@ -1113,14 +1172,14 @@ func (h *BufPane) ToggleHelp() bool { } else { h.openHelp("help") } - return false + return true } // ToggleKeyMenu toggles the keymenu option and resizes all tabs func (h *BufPane) ToggleKeyMenu() bool { config.GlobalSettings["keymenu"] = !config.GetGlobalOption("keymenu").(bool) Tabs.Resize() - return false + return true } // ShellMode opens a terminal to run a shell command @@ -1132,7 +1191,7 @@ func (h *BufPane) ShellMode() bool { } }) - return false + return true } // CommandMode lets the user enter a command @@ -1142,18 +1201,18 @@ func (h *BufPane) CommandMode() bool { h.HandleCommand(resp) } }) - return false + return true } // ToggleOverwriteMode lets the user toggle the text overwrite mode func (h *BufPane) ToggleOverwriteMode() bool { h.isOverwriteMode = !h.isOverwriteMode - return false + return true } // Escape leaves current mode func (h *BufPane) Escape() bool { - return false + return true } // Quit this will close the current tab or view that is open @@ -1188,7 +1247,7 @@ func (h *BufPane) Quit() bool { } else { quit() } - return false + return true } // QuitAll quits the whole editor; all splits and tabs @@ -1220,7 +1279,7 @@ func (h *BufPane) QuitAll() bool { quit() } - return false + return true } // AddTab adds a new tab with an empty buffer @@ -1232,7 +1291,7 @@ func (h *BufPane) AddTab() bool { Tabs.AddTab(tp) Tabs.SetActive(len(Tabs.List) - 1) - return false + return true } // PreviousTab switches to the previous tab in the tab list @@ -1240,28 +1299,28 @@ func (h *BufPane) PreviousTab() bool { a := Tabs.Active() Tabs.SetActive(util.Clamp(a-1, 0, len(Tabs.List)-1)) - return false + return true } // NextTab switches to the next tab in the tab list func (h *BufPane) NextTab() bool { a := Tabs.Active() Tabs.SetActive(util.Clamp(a+1, 0, len(Tabs.List)-1)) - return false + return true } // VSplitAction opens an empty vertical split func (h *BufPane) VSplitAction() bool { h.VSplitBuf(buffer.NewBufferFromString("", "", buffer.BTDefault)) - return false + return true } // HSplitAction opens an empty horizontal split func (h *BufPane) HSplitAction() bool { h.HSplitBuf(buffer.NewBufferFromString("", "", buffer.BTDefault)) - return false + return true } // Unsplit closes all splits in the current tab except the active one @@ -1272,7 +1331,7 @@ func (h *BufPane) Unsplit() bool { MainTab().RemovePane(MainTab().GetPane(h.splitID)) MainTab().Resize() MainTab().SetActive(len(MainTab().Panes) - 1) - return false + return true } // NextSplit changes the view to the next split @@ -1286,7 +1345,7 @@ func (h *BufPane) NextSplit() bool { MainTab().SetActive(a) - return false + return true } // PreviousSplit changes the view to the previous split @@ -1299,7 +1358,7 @@ func (h *BufPane) PreviousSplit() bool { } MainTab().SetActive(a) - return false + return true } var curmacro []interface{} @@ -1314,6 +1373,7 @@ func (h *BufPane) ToggleMacro() bool { } else { InfoBar.Message("Stopped recording") } + h.Relocate() return true } @@ -1330,6 +1390,7 @@ func (h *BufPane) PlayMacro() bool { h.DoKeyEvent(t) } } + h.Relocate() return true } @@ -1339,6 +1400,7 @@ func (h *BufPane) SpawnMultiCursor() bool { if !spawner.HasSelection() { spawner.SelectWord() h.multiWord = true + h.Relocate() return true } @@ -1369,6 +1431,7 @@ func (h *BufPane) SpawnMultiCursor() bool { InfoBar.Message("No matches found") } + h.Relocate() return true } @@ -1403,7 +1466,7 @@ func (h *BufPane) SpawnMultiCursorSelect() bool { return false } InfoBar.Message("Added cursors from selection") - return false + return true } // MouseMultiCursor is a mouse action which puts a new cursor at the mouse position @@ -1415,7 +1478,7 @@ func (h *BufPane) MouseMultiCursor(e *tcell.EventMouse) bool { b.AddCursor(c) b.MergeCursors() - return false + return true } // SkipMultiCursor moves the current multiple cursor to the next available position @@ -1446,6 +1509,7 @@ func (h *BufPane) SkipMultiCursor() bool { } else { InfoBar.Message("No matches found") } + h.Relocate() return true } @@ -1458,6 +1522,7 @@ func (h *BufPane) RemoveMultiCursor() bool { } else { h.multiWord = false } + h.Relocate() return true } @@ -1465,9 +1530,11 @@ func (h *BufPane) RemoveMultiCursor() bool { func (h *BufPane) RemoveAllMultiCursors() bool { h.Buf.ClearCursors() h.multiWord = false + h.Relocate() return true } +// None is an action that does nothing func (h *BufPane) None() bool { - return false + return true } diff --git a/internal/action/bindings.go b/internal/action/bindings.go index 7cad325a..18fdfa33 100644 --- a/internal/action/bindings.go +++ b/internal/action/bindings.go @@ -422,8 +422,8 @@ func DefaultBindings() map[string]string { "Backspace": "Backspace", "Alt-CtrlH": "DeleteWordLeft", "Alt-Backspace": "DeleteWordLeft", - "Tab": "InsertTab", - "Backtab": "OutdentLine", + "Tab": "Autocomplete|IndentSelection|InsertTab", + "Backtab": "OutdentSelection|OutdentLine", "CtrlO": "OpenFile", "CtrlS": "Save", "CtrlF": "Find", diff --git a/internal/action/bufpane.go b/internal/action/bufpane.go index 4c70669b..9df8779e 100644 --- a/internal/action/bufpane.go +++ b/internal/action/bufpane.go @@ -53,18 +53,35 @@ func LuaAction(fn string) func(*BufPane) bool { // BufMapKey maps a key event to an action func BufMapKey(k Event, action string) { - actions := strings.SplitN(action, ",", -1) BufKeyStrings[k] = action - actionfns := make([]func(*BufPane) bool, len(actions)) - for i, a := range actions { - // a = strings.TrimSpace(a) + var actionfns []func(*BufPane) bool + var names []string + var types []byte + for i := 0; ; i++ { + if action == "" { + break + } + + idx := strings.IndexAny(action, "&|,") + a := action + if idx >= 0 { + a = action[:idx] + types = append(types, action[idx]) + action = action[idx+1:] + } else { + types = append(types, ' ') + action = "" + } + var afn func(*BufPane) bool if strings.HasPrefix(action, "command:") { a = strings.SplitN(a, ":", 2)[1] afn = CommandAction(a) + names = append(names, "") } else if strings.HasPrefix(a, "command-edit:") { a = strings.SplitN(a, ":", 2)[1] afn = CommandEditAction(a) + names = append(names, "") } else if strings.HasPrefix(a, "lua:") { a = strings.SplitN(a, ":", 2)[1] afn = LuaAction(a) @@ -72,19 +89,31 @@ func BufMapKey(k Event, action string) { screen.TermMessage("Lua Error:", action, "does not exist") continue } + names = append(names, "") } else if f, ok := BufKeyActions[a]; ok { afn = f + names = append(names, a) } else { screen.TermMessage("Error:", action, "does not exist") + continue } - actionfns[i] = afn + actionfns = append(actionfns, afn) } BufKeyBindings[k] = func(h *BufPane) bool { - b := false - for _, a := range actionfns { - b = a(h) || b + cursors := h.Buf.GetCursors() + success := true + for i, a := range actionfns { + for j, c := range cursors { + h.Buf.SetCurCursor(c.Num) + h.Cursor = c + if i == 0 || (success && types[i-1] == '&') || (!success && types[i-1] == '|') || (types[i-1] == ',') { + success = h.execAction(a, names[i], j) + } else { + break + } + } } - return b + return true } } @@ -291,43 +320,34 @@ func (h *BufPane) HandleEvent(event tcell.Event) { // to and executing it (possibly multiple times for multiple cursors) func (h *BufPane) DoKeyEvent(e Event) bool { if action, ok := BufKeyBindings[e]; ok { - estr := BufKeyStrings[e] - if estr != "InsertTab" { - h.Buf.HasSuggestions = false - } - for _, s := range MultiActions { - if s == estr { - cursors := h.Buf.GetCursors() - for _, c := range cursors { - h.Buf.SetCurCursor(c.Num) - h.Cursor = c - if !h.PluginCB("pre" + estr) { - // canceled by plugin - continue - } - rel := action(h) - if h.PluginCB("on"+estr) && rel { - h.Relocate() - } + return action(h) + } + return false +} - if recording_macro { - if estr != "ToggleMacro" && estr != "PlayMacro" { - curmacro = append(curmacro, e) - } +func (h *BufPane) execAction(action func(*BufPane) bool, name string, cursor int) bool { + if name != "Autocomplete" { + h.Buf.HasSuggestions = false + } + + _, isMulti := MultiActions[name] + if (!isMulti && cursor == 0) || isMulti { + if h.PluginCB("pre" + name) { + asuccess := action(h) + psuccess := h.PluginCB("on" + name) + + if isMulti { + if recording_macro { + if name != "ToggleMacro" && name != "PlayMacro" { + curmacro = append(curmacro, action) } } - return true } + + return asuccess && psuccess } - if !h.PluginCB("pre" + estr) { - return false - } - rel := action(h) - if h.PluginCB("on"+estr) && rel { - h.Relocate() - } - return true } + return false } @@ -469,6 +489,7 @@ var BufKeyActions = map[string]BufKeyAction{ "MoveLinesDown": (*BufPane).MoveLinesDown, "IndentSelection": (*BufPane).IndentSelection, "OutdentSelection": (*BufPane).OutdentSelection, + "Autocomplete": (*BufPane).Autocomplete, "OutdentLine": (*BufPane).OutdentLine, "Paste": (*BufPane).Paste, "PastePrimary": (*BufPane).PastePrimary, @@ -529,52 +550,52 @@ var BufMouseActions = map[string]BufMouseAction{ // times if there are multiple cursors (one per cursor) // Generally actions that modify global editor state like quitting or // saving should not be included in this list -var MultiActions = []string{ - "CursorUp", - "CursorDown", - "CursorPageUp", - "CursorPageDown", - "CursorLeft", - "CursorRight", - "CursorStart", - "CursorEnd", - "SelectToStart", - "SelectToEnd", - "SelectUp", - "SelectDown", - "SelectLeft", - "SelectRight", - "WordRight", - "WordLeft", - "SelectWordRight", - "SelectWordLeft", - "DeleteWordRight", - "DeleteWordLeft", - "SelectLine", - "SelectToStartOfLine", - "SelectToEndOfLine", - "ParagraphPrevious", - "ParagraphNext", - "InsertNewline", - "Backspace", - "Delete", - "InsertTab", - "FindNext", - "FindPrevious", - "Cut", - "CutLine", - "DuplicateLine", - "DeleteLine", - "MoveLinesUp", - "MoveLinesDown", - "IndentSelection", - "OutdentSelection", - "OutdentLine", - "Paste", - "PastePrimary", - "SelectPageUp", - "SelectPageDown", - "StartOfLine", - "EndOfLine", - "JumpToMatchingBrace", +var MultiActions = map[string]bool{ + "CursorUp": true, + "CursorDown": true, + "CursorPageUp": true, + "CursorPageDown": true, + "CursorLeft": true, + "CursorRight": true, + "CursorStart": true, + "CursorEnd": true, + "SelectToStart": true, + "SelectToEnd": true, + "SelectUp": true, + "SelectDown": true, + "SelectLeft": true, + "SelectRight": true, + "WordRight": true, + "WordLeft": true, + "SelectWordRight": true, + "SelectWordLeft": true, + "DeleteWordRight": true, + "DeleteWordLeft": true, + "SelectLine": true, + "SelectToStartOfLine": true, + "SelectToEndOfLine": true, + "ParagraphPrevious": true, + "ParagraphNext": true, + "InsertNewline": true, + "Backspace": true, + "Delete": true, + "InsertTab": true, + "FindNext": true, + "FindPrevious": true, + "Cut": true, + "CutLine": true, + "DuplicateLine": true, + "DeleteLine": true, + "MoveLinesUp": true, + "MoveLinesDown": true, + "IndentSelection": true, + "OutdentSelection": true, + "OutdentLine": true, + "Paste": true, + "PastePrimary": true, + "SelectPageUp": true, + "SelectPageDown": true, + "StartOfLine": true, + "EndOfLine": true, + "JumpToMatchingBrace": true, }