mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-29 22:27:13 +09:00
Add support for macros
Closes #270 CtrlU to toggle recording and CtrlJ to playback. You can also rebind using the "ToggleMacro" and "PlayMacro" actions. Note that recursive macros are not yet supported.
This commit is contained in:
@@ -1476,6 +1476,62 @@ func (v *View) PreviousSplit(usePlugin bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var curMacro []interface{}
|
||||
var recordingMacro bool
|
||||
|
||||
func (v *View) ToggleMacro(usePlugin bool) bool {
|
||||
if usePlugin && !PreActionCall("ToggleMacro", v) {
|
||||
return false
|
||||
}
|
||||
|
||||
recordingMacro = !recordingMacro
|
||||
|
||||
if recordingMacro {
|
||||
curMacro = []interface{}{}
|
||||
messenger.Message("Recording")
|
||||
} else {
|
||||
messenger.Message("Stopped recording")
|
||||
}
|
||||
|
||||
if usePlugin {
|
||||
return PostActionCall("ToggleMacro", v)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (v *View) PlayMacro(usePlugin bool) bool {
|
||||
if usePlugin && !PreActionCall("PlayMacro", v) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, action := range curMacro {
|
||||
switch t := action.(type) {
|
||||
case rune:
|
||||
// Insert a character
|
||||
if v.Cursor.HasSelection() {
|
||||
v.Cursor.DeleteSelection()
|
||||
v.Cursor.ResetSelection()
|
||||
}
|
||||
v.Buf.Insert(v.Cursor.Loc, string(t))
|
||||
v.Cursor.Right()
|
||||
|
||||
for _, pl := range loadedPlugins {
|
||||
_, err := Call(pl+".onRune", string(t), v)
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") {
|
||||
TermMessage(err)
|
||||
}
|
||||
}
|
||||
case func(*View, bool) bool:
|
||||
t(v, true)
|
||||
}
|
||||
}
|
||||
|
||||
if usePlugin {
|
||||
return PostActionCall("PlayMacro", v)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// None is no action
|
||||
func None() bool {
|
||||
return false
|
||||
|
||||
@@ -79,6 +79,8 @@ var bindingActions = map[string]func(*View, bool) bool{
|
||||
"NextTab": (*View).NextTab,
|
||||
"NextSplit": (*View).NextSplit,
|
||||
"PreviousSplit": (*View).PreviousSplit,
|
||||
"ToggleMacro": (*View).ToggleMacro,
|
||||
"PlayMacro": (*View).PlayMacro,
|
||||
|
||||
// This was changed to InsertNewline but I don't want to break backwards compatibility
|
||||
"InsertEnter": (*View).InsertNewline,
|
||||
@@ -408,6 +410,8 @@ func DefaultBindings() map[string]string {
|
||||
"CtrlQ": "Quit",
|
||||
"CtrlE": "CommandMode",
|
||||
"CtrlW": "NextSplit",
|
||||
"CtrlU": "ToggleMacro",
|
||||
"CtrlJ": "PlayMacro",
|
||||
|
||||
// Emacs-style keybindings
|
||||
"Alt-f": "WordRight",
|
||||
|
||||
@@ -3,6 +3,8 @@ package main
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -217,3 +219,7 @@ func Abs(n int) int {
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func FuncName(i interface{}) string {
|
||||
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
|
||||
}
|
||||
|
||||
@@ -340,6 +340,10 @@ func (v *View) HandleEvent(event tcell.Event) {
|
||||
TermMessage(err)
|
||||
}
|
||||
}
|
||||
|
||||
if recordingMacro {
|
||||
curMacro = append(curMacro, e.Rune())
|
||||
}
|
||||
} else {
|
||||
for key, actions := range bindings {
|
||||
if e.Key() == key.keyCode {
|
||||
@@ -352,6 +356,12 @@ func (v *View) HandleEvent(event tcell.Event) {
|
||||
relocate = false
|
||||
for _, action := range actions {
|
||||
relocate = action(v, true) || relocate
|
||||
funcName := FuncName(action)
|
||||
if funcName != "main.(*View).ToggleMacro" && funcName != "main.(*View).PlayMacro" {
|
||||
if recordingMacro {
|
||||
curMacro = append(curMacro, action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user